【JavaWeb開發】初步實現網站應用釘釘掃碼登入
寫在前面:如果你還不知道釘釘是什麼,就趕緊問問Google。當然,這篇部落格是用流水線的形式完成釘釘掃碼登入。
第一步,看官方文件
如果你想要通過使用者掃碼獲取到他的個人資訊,那麼你需要完成全部的互動,如果你只是想為你的網站做一個免登入處理,其實只要拿到使用者的openid就可以了。當然我會在這篇部落格中貼出全部步驟的程式碼。
第二步,獲取appId和appSecret
- 在左側的五個選單中點選自助工具,然後在右側的選單中建立掃碼登入應用授權,然後依次輸入名稱、描述、授權頁面logo地址(這個圖片最後會出現在使用者掃碼裝置中,建議使用壓縮圖片減少使用者載入時間)、回撥域名
第三步,建立一個使用者掃碼介面並獲取臨時code
官網一共給大家提供了兩種方式,第一種就是直接跳轉到釘釘的二維碼掃描;第二種是嵌入到自己的網頁顯示二維碼。
因為我用的是第一種,並且這篇部落格也僅僅是建立在初步實現,所以這裡就不為大家介紹第二種嵌入方式了。
- 獲取臨時code和引數state,首先再看一次官網說明文件:
所以你在REDIRECT_URI跳轉回去的方法中,需要獲取到code和state兩個引數。而關於state,引數其實就是你在之前拼接URL的時候中的STATE,這裡建議大家可以使用時間戳(當用戶訪問的時候,因為URL不同,所以瀏覽器會重新獲取,避免瀏覽器因快取而導致二維碼無法使用等問題);
程式碼:
- 拼接URL:
/**
*
* 描述:後臺預設跳轉到二維碼登入介面
* 開發人員:暴沸
* 開發時間: 2017年2月23日 下午9:09:57
* 聯絡方式:[email protected]
*
* @param request
*/
@RequestMapping(value="login")
public void toALiDingDing(HttpServletResponse response){
//這是我自己寫的一個獲取時間戳的Util,前期大家可以不管這個STATE
TimeUtil timeUtil = new TimeUtil();
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("https://oapi.dingtalk.com/connect/qrconnect?appid=APPID&")
.append("response_type=code&scope=snsapi_login&state=")
.append(timeUtil.getNow())
.append("&redirect_uri=")
.append("REDIRECT_URI");
try {
response.sendRedirect(stringBuilder.toString());
} catch (IOException e1) {
}
}
第四步,獲取access_token
- 首先我們還是看一下官方說明文件:
獲取釘釘開放應用的ACCESS_TOKEN(釘釘官網)
所以我們需要使用java程式碼向釘釘伺服器端傳送一個GET請求
//獲取accesstoken
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
HttpClient httpClient = httpClientBuilder.build();
HttpResponse httpResponse = null;
String url = "https://oapi.dingtalk.com/sns/gettoken?appid=APPID&appsecret=APPSECRET";
HttpGet httpGet = new HttpGet(url);
try {
httpResponse = httpClient.execute(httpGet);
} catch (Exception e) {
}
BufferedReader bufferedReader = null;
StringBuilder entityStringBuilder=new StringBuilder();
//得到httpResponse的狀態響應碼
int statusCode=httpResponse.getStatusLine().getStatusCode();
if (statusCode==HttpStatus.SC_OK) {
//得到httpResponse的實體資料
HttpEntity httpEntity=httpResponse.getEntity();
if (httpEntity!=null) {
try {
bufferedReader=new BufferedReader
(new InputStreamReader(httpEntity.getContent(), "UTF-8"), 8*1024);
String line=null;
while ((line=bufferedReader.readLine())!=null) {
entityStringBuilder.append(line+"/n");
}
} catch (Exception e) {
}
}
}
JSONObject jsonObject = new JSONObject(entityStringBuilder.toString());
String access_token = jsonObject.getString("access_token");
第五步,獲取持久授權碼persistent_code
在官網文件中指出,需要使用之前獲取到的臨時code以及access_token兩個引數來發送一個POST請求:
//獲取使用者授權的持久授權碼
String url3 = "https://oapi.dingtalk.com/sns/get_persistent_code?access_token="+access_token;
System.out.println("url3="+url3);
HttpPost httpPost3 = new HttpPost(url3);
//封裝臨時授權碼
JSONObject jsonObject3_1 = new JSONObject();
jsonObject3_1.put("tmp_auth_code", code);
HttpEntity httpEntity3 = null;
httpEntity3 = new StringEntity(jsonObject3_1.toString(),"UTF-8");
httpPost3.setEntity(httpEntity3);
HttpResponse httpResponse3 = null;
try {
httpResponse3 = httpClient.execute(httpPost3);
} catch (Exception e) {
// TODO: handle exception
}
StringBuilder entityStringBuilder3=new StringBuilder();
//得到httpResponse的狀態響應碼
int statusCode3=httpResponse3.getStatusLine().getStatusCode();
if (statusCode3==HttpStatus.SC_OK) {
//得到httpResponse的實體資料
HttpEntity httpEntity3_2=httpResponse3.getEntity();
if (httpEntity3!=null) {
try {
bufferedReader=new BufferedReader
(new InputStreamReader(httpEntity3_2.getContent(), "UTF-8"), 8*1024);
String line=null;
while ((line=bufferedReader.readLine())!=null) {
entityStringBuilder3.append(line+"/n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
JSONObject jsonObject3_2 = new JSONObject(entityStringBuilder3.toString());
String persistent_code = jsonObject3_2.getString("persistent_code");
String openid = jsonObject3_2.getString("openid");
如果你自習看程式碼,在這一步中我們已經拿到了使用者在這個網頁應用中的唯一標識openid了,其實到這裡就可以實現網站的免登入掃碼了哦!
第六步,獲取SNS_TOKEN
文件指出,我們需要在POST請求中封裝之前獲取到的access_token、openid以及persistent_code
//獲取使用者授權的SNS_TOKEN
String url4 = "https://oapi.dingtalk.com/sns/get_sns_token?access_token="+access_token;
HttpPost httpPost4 = new HttpPost(url4);
JSONObject jsonObject4 = new JSONObject();
jsonObject4.put("openid", openid);
jsonObject4.put("persistent_code", persistent_code);
HttpEntity httpEntity4 = null;
httpEntity4 = new StringEntity(jsonObject4.toString(),"UTF-8");
httpPost4.setEntity(httpEntity4);
HttpResponse httpResponse4 = null;
//重新獲取一個新的httpClient
HttpClientBuilder httpClientBuilder2 = HttpClientBuilder.create();
HttpClient httpClient2 = httpClientBuilder2.build();
try {
httpResponse4 = httpClient2.execute(httpPost4);
} catch (Exception e) {
// TODO: handle exception
}
StringBuilder entityStringBuilder4=new StringBuilder();
//得到httpResponse的狀態響應碼
int statusCode4=httpResponse4.getStatusLine().getStatusCode();
if (statusCode4==HttpStatus.SC_OK) {
//得到httpResponse的實體資料
HttpEntity httpEntity4_1=httpResponse4.getEntity();
if (httpEntity4_1!=null) {
try {
bufferedReader=new BufferedReader
(new InputStreamReader(httpEntity4_1.getContent(), "UTF-8"), 8*1024);
String line=null;
while ((line=bufferedReader.readLine())!=null) {
entityStringBuilder4.append(line+"/n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
//
JSONObject jsonObject4_1 = new JSONObject(entityStringBuilder4.toString());
String sns_token = jsonObject4_1.getString("sns_token");
勝利就在眼前了!
第七步,獲取使用者資訊
直接傳送GET請求即可!
//獲取使用者授權的個人資訊
String url5 = "https://oapi.dingtalk.com/sns/getuserinfo?sns_token="+sns_token;
HttpGet httpGet5 = new HttpGet(url5);
HttpResponse httpResponse5 = null;
try {
HttpClient httpClient3 = httpClientBuilder.build();
httpResponse5 = httpClient3.execute(httpGet5);
} catch (Exception e) {
// TODO: handle exception
}
StringBuilder entityStringBuilder5=new StringBuilder();
//得到httpResponse的狀態響應碼
int statusCode5=httpResponse5.getStatusLine().getStatusCode();
if (statusCode5==HttpStatus.SC_OK) {
//得到httpResponse的實體資料
HttpEntity httpEntity5=httpResponse5.getEntity();
if (httpEntity5!=null) {
try {
bufferedReader=new BufferedReader
(new InputStreamReader(httpEntity5.getContent(), "UTF-8"), 8*1024);
String line=null;
while ((line=bufferedReader.readLine())!=null) {
entityStringBuilder5.append(line+"/n");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
JSONObject jsonObject5_1 = new JSONObject(entityStringBuilder5.toString());
JSONObject jsonObject5 = jsonObject5_1.getJSONObject("user_info");
String nick = jsonObject5.getString("nick");
String unionid = jsonObject5.getString("unionid");
String dingId = jsonObject5.getString("dingId");
大功搞成!
當然,這篇部落格只是用流水線的方式去寫這個接入的過程,實際上應該對程式碼進行優化,比如access_token應該使用定時任務獲取,如果每次都在使用者掃碼的時候去獲取,會佔用大量資源。
相關推薦
【JavaWeb開發】初步實現網站應用釘釘掃碼登入
寫在前面:如果你還不知道釘釘是什麼,就趕緊問問Google。當然,這篇部落格是用流水線的形式完成釘釘掃碼登入。 第一步,看官方文件 如果你想要通過使用者掃碼獲取到他的個人資訊,那麼你需要完成全部的互動,如果你只是想為你的網站做一個免登入處理,其實
【Android開發】如何實現android和伺服器長連線呢?推送訊息的原理
GGSN(Gateway GPRS Support Node 閘道器GPRS支援結點)模組就實現了NAT功能。因為大部分移動無線網路運營商都是為了減少閘道器的NAT對映表的負荷,所以如果發現鏈路中有一段時間沒有資料通訊時,會刪除其對應表,造成鏈路中斷。(關於NAT的作用及其原理可以檢視我的另一篇博文:關於使用
【Android開發】如何實現android和伺服器長連線呢?
GGSN(Gateway GPRS Support Node 閘道器GPRS支援結點)模組就實現了NAT功能。因為大部分移動無線網路運營商都是為了減少閘道器的NAT對映表的負荷,所以如果發現鏈路中有一段時間沒有資料通訊時,會刪除其對應表,造成鏈路中斷。(關於NAT的作用及其原理可以檢視我的另一篇博文:關於使用
【外掛分享】如何實現EmPireCMS帝國系統簡訊驗證碼功能
找到了一家不錯的簡訊外掛,有需要對接的可以檢視學習,在這邊分享一下,有需要的可以詳細看看,瞭解一下。http://www.ihuyi.com/ 外掛說明 本外掛系互億無線針對EmpireCMS v7.2 utf-8版本開發,外掛內的所有檔案均為對原檔案的修改,如果你的系統經過二次開發,安裝本外掛之前,請仔
利用長輪詢實現微信網頁版掃碼登入
掃碼登入操作過程 手機登入微信,利用“掃一掃”功能掃描網頁上的二維碼手機掃描成功後,提示“登入網頁版微信”;網頁上顯示“成功掃描 請在手機點選確認以登入”手機端點選“登入網頁版微信”,網頁跳轉到使用者的微信操作介面 整個掃碼登入的操作過程還是挺簡單的,而且互動地實時性比較
【javaweb】BootStrap實現網站首頁
運用BootStrap框架對最開始的網站首頁進行一個重寫。 效果如下: 原始碼如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>
Android基於XMPP Smack Openfire開發IM【四】初步實現兩個客戶端通訊
本部落格要介紹的內容: Openfire做伺服器端,兩個客戶端:Spark、android模擬器。實現兩個客戶端之間的通訊。 第一步:啟動openfire伺服器。(這裡需要用到兩個使用者登入,前面的部落格中已經說明如何新增使用者了。) [img] [/img] 第
【Web開發】Mean web開發 01-Express實現MVC模式開發
http scripts send javascrip 模板引擎 指令 開發環境 depend filter 簡介 Mean是JavaScript的全棧開發框架。更多介紹 用Express實現MVC模式開發是Mean Web全棧開發中的一部分。 Express 是一個基於
【原始碼分享】java實現對接簡訊驗證碼應用功能
今天公司提出一個需求,要在現有專案上收集註冊使用者的真實手機號,由於之前沒有接觸過這一塊,只能尋求度孃的幫助,經過一天的努力,終於完成了,現整理記錄下已備查閱。 1 解決方案:在註冊時要求使用者進行手機驗證。2 尋找簡訊供應商:由於對這一塊不是太懂,大學同學推薦一家他們公司在用的給我。3 程式碼實現 首先到
【遊戲開發】遊戲視窗實現自定義貼圖
//Windows視窗標頭檔案 #include <windows.h> //PlaySound函式包含的標頭檔案 #pragma comment(lib,"winmm.lib") //視窗寬度 #define WINDOW_WIDTH 1132 //視窗高度 #define
【遊戲開發】實現簡單對話方塊及音樂播放
//Windows視窗標頭檔案 #include <Windows.h> //PlaySound函式包含的標頭檔案 #pragma comment(lib,"winmm.lib") //主函式 int WINAPI WinMain(HINSTANCE hInstance,HINSTA
【Python web 開發】viewset 實現商品詳情頁的介面
我們如何來完成商品詳情頁的介面呢? 首先要配置一個商品詳情的url 按照我們正常的介面配法 ,應該是後面要加一個id 的,為什麼這裡沒有加id 呢? ,應該是rooter register 的作用吧,等我在學習一遍基礎再來回答? 那麼我們再來寫viewset Mixin.Retriev
【Android應用開發】-(9)應用程式安裝解除安裝原理
本文粗體部分來自網路上的一篇文章,已不知出處,知道的告知,在此謝謝原作者。引出安裝解除安裝的原理之前,先實現一個簡單的安裝解除安裝應用程式的功能。文章是我之前寫的一篇部落格,這裡就不在敘述,只補充幾點: 1、由於程式碼中用到了PackageInstallObserver,PackageInstallObse
【mahout筆記】初步理解userCF(基於使用者的推薦演算法)在mahout的實現
昨天嘗試在java中搭建了一個mahout的小demo,實現的就是基於使用者的推薦演算法。程式碼如下(更多程式碼和測試資料庫)參見前一篇: public class RecommendTest { final static int NEIGHBORHOOD_NUM =
【模組開發】商品購物車的實現——3.使用者新增刪除商品的操作(控制層)
1.主頁面實現新增 首先在我們的主頁面相關的按鈕上加上連線地址的跳轉,轉到一個jsp頁面,這個jsp頁面實現的是新增商品的功能。index,jsp中需要加入的程式碼,例如:<!-- 在這裡將商品加入購物車 --><a href="addGood.jsp?i
【嵌入式開發】自定義AT指令實現sniffer網路嗅探功能
基礎 該功能是在NON-OS SDK下實現的。 Non-OS SDK 是不不基於作業系統的 SDK,提供 IOT_Demo 和 AT 的編譯。Non-OS SDK 主要使⽤用定時器和回撥函式的方式實現各個功能事件的巢狀,達到特定條件下觸發特定功能函式的目
【模組開發】商品購物車的實現——1.功能分析和效果演示
1.工程說明 前面在學習jsp中cookie內容的時候,我們寫了一個demo:商品瀏覽記錄功能的實現。現在,我們將在前面的那個工程上進行優化開發(主要是懶)。 回顧一下前面的那個工程實現了那些功能:商品資訊顯示頁面,單個商品資訊詳情頁面,近五條瀏覽商品記錄的頁面。 那麼
【視訊開發】【Live555】live555實現h264碼流RTSP傳輸
1.概述 liveMedia 庫中有一系列類,基類是Medium,這些類針對不同的流媒體型別和編碼。 其中的StreamFrame類檔案(如MPEG4VideoStreamFramer)為流傳輸關鍵。 2 重要概念: StreamFrame類:該類繼承Framed
【JNI開發】C++呼叫java函式的實現方法
本文的主要內容:C++中呼叫java類的成員函式和靜態成員函式 1,java程式碼 public class SNaviEngineManager { public void sendMe
【Python開發】C和Python之間的介面實現
## 更新:關於ctypes,見拙作 聊聊Python ctypes 模組 - 蛇之魅惑 - 知乎專欄 屬於混合程式設計的問題。較全面的介紹一下,不僅限於題主提出的問題。 以下討論中,Python指它的標準實現,即CPython(雖然不是很嚴格) 本文分4個部分C/C++ 呼叫 Python (基礎篇)—