【JavaWeb開發】初步實現網站應用釘釘掃碼登錄


目錄(?)[+]

寫在前面:如果你還不知道釘釘是什么,就趕緊問問Google。當然,這篇博客是用流水線的形式完成釘釘掃碼登錄。

第一步,看官方文檔

網站應用釘釘掃碼登錄開發指南(釘釘官網)

如果你想要通過用戶掃碼獲取到他的個人信息,那么你需要完成全部的交互,如果你只是想為你的網站做一個免登錄處理,其實只要拿到用戶的openid就可以了。當然我會在這篇博客中貼出全部步驟的代碼。

第二步,獲取appId和appSecret

  • 登錄/注冊到釘釘開發者官網:新版開發者平台:http://open-dev.dingtalk.com
  • 在左側的五個菜單中點擊自助工具,然后在右側的菜單中創建掃碼登錄應用授權,然后依次輸入名稱描述授權頁面logo地址(這個圖片最后會出現在用戶掃碼設備中,建議使用壓縮圖片減少用戶加載時間)、回調域名(一般都是寫一個子域名,比如http://oa.dingtalk.com),保存之后便可以看到對應的appId以及appSecret了。

第三步,創建一個用戶掃碼界面並獲取臨時code

官網一共給大家提供了兩種方式,第一種就是直接跳轉到釘釘的二維碼掃描;第二種是嵌入到自己的網頁顯示二維碼。

因為我用的是第一種,並且這篇博客也僅僅是建立在初步實現,所以這里就不為大家介紹第二種嵌入方式了。

https://oapi.dingtalk.com/connect/qrconnect?appid=APPID&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=REDIRECT_URI

將自己的appid填寫在APPID處,將自己希望掃碼后跳轉到的地址填寫在REDIRECT_URI,比如可以填寫為http://google.com/dingtalkLogin或者http://google.com/dingtalkLogin.action等等,大家可以根據自己的實際情況填寫。

  • 獲取臨時code和參數state,首先再看一次官網說明文檔:
    這里寫圖片描述
    所以你在REDIRECT_URI跳轉回去的方法中,需要獲取到code和state兩個參數。而關於state,參數其實就是你在之前拼接URL的時候中的STATE,這里建議大家可以使用時間戳(當用戶訪問的時候,因為URL不同,所以瀏覽器會重新獲取,避免瀏覽器因緩存而導致二維碼無法使用等問題);

代碼:

  • 拼接URL:
    /** * * 描述:后台默認跳轉到二維碼登錄界面 * 開發人員:暴沸 * 開發時間: 2017年2月23日 下午9:09:57 * 聯系方式:admin@baofeidyz.com * * @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) { } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

第四步,獲取access_token

關於Java如何封裝get和post請求可以參考一下我自己寫的博客:
【JavaWeb開發】用Apache的HttpClient4.5完成HttpGet請求
【JavaWeb開發】用Apache的HttpClient4.5完成HttpPost請求

        //獲取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");
  • 1
  • 2

第五步,獲取持久授權碼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");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

如果你自習看代碼,在這一步中我們已經拿到了用戶在這個網頁應用中的唯一標識openid了,其實到這里就可以實現網站的免登錄掃碼了哦!

第六步,獲取SNS_TOKEN

獲取用戶授權的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");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

勝利就在眼前了!

第七步,獲取用戶信息

獲取用戶授權的個人信息(釘釘官網)

直接發送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");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

大功搞成!

當然,這篇博客只是用流水線的方式去寫這個接入的過程,實際上應該對代碼進行優化,比如access_token應該使用定時任務獲取,如果每次都在用戶掃碼的時候去獲取,會占用大量資源。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM