天天看點

OAuth 2.0認證-授權碼模式的了解和執行個體分析

目前OAuth 2.0 認證有五種方式,見官方文檔: http://www.rfcreader.com/#rfc6749

授權碼模式(Authorization Code Grant)

流程圖

OAuth 2.0認證-授權碼模式的了解和執行個體分析

說明:

1,認證伺服器是一個業務無關的系統;

2,code就是授權碼,隻能使用一次;

3,token 在有效期内可以無限次使用

場景化講解-下單

場景:A 公司旗下有很多 web 産品,同時還有一個應用商店(類似京東)負責售賣這些軟體産品,下面以使用者進入應用商店購買産品的流程着手。

  1. 應用商店通過浏覽器嘗試擷取下單頁;
  2. 應用商店背景鑒權,發現沒有登入(應用商店背景實際會調用認證伺服器,比如校驗 access tokensh是否有效);
  3. 跳轉到登入頁面;(對應上圖(A))
  4. 使用者通過浏覽器輸入使用者名,密碼等方式進行授權(此時會調用認證伺服器接口);(對應上圖(B))
  5. 認證伺服器傳回臨時 code 給浏覽器;(對應上圖(C))
  6. 應用商店拿臨時 code 去調用認證伺服器接口,換取 access token;(對應上圖(D))
  7. 認證伺服器傳回 access token給應用商店;(對應上圖(E))
  8. 應用商店把 access token 緩存下來。
  9. 後續應用商店調用業務系統(比如下單接口,訂單查詢接口)接口均帶上 access token;

場景化講解-微信公衆号授權

現在很多微商系統接入了微信公衆号,通過微信公衆号售賣産品,那麼它們是如何擷取使用者資訊的呢?

我們在關注某個商店性質的微信公衆号時,經常會彈出如下對話框,要求我們授權

OAuth 2.0認證-授權碼模式的了解和執行個體分析

圖2-1

使用者點選上述界面中的"允許",對應的操作是“"授權碼模式"的(B)-- User authenticates:

OAuth 2.0認證-授權碼模式的了解和執行個體分析

具體流程如下:

  1. 某微信公衆号B 通路使用者資訊,用于下單支付(實際需要使用者的 openid);
  2. 見圖2-1,微信彈框,要求使用者授權;
  3. 使用者點選"允許"授權,某微信公衆号B才能擷取到臨時 code;
  4. 某微信公衆号B拿臨時 code調用微信鑒權接口擷取 access token 或 openid;

執行個體3-對接釘釘通訊錄實作登入

免登流程

第一步:通過使用者授權擷取code

授權連結:

https://h5.dingtalk.com/liveeasylogin/index.html#/index?appid=dingoae2vmockd44q2&response_type=code&scope=snsapi_auth&state=STATE&redirect_uri=http%3A%2F%2Flocalhost%3A7001%2Fapi%2Ftest%2FtestCode.json

第二步:使用者授權

OAuth 2.0認證-授權碼模式的了解和執行個體分析

授權成功擷取code

{"content":"code=4d9954574c32afafd9xxx3c34b414aa&state=STATE","errorLevel":0,"success":true}           
OAuth 2.0認證-授權碼模式的了解和執行個體分析

code 值為:4d9954574c32afafd9xxx3c34b414aa

授權測試位址

dingtalk://dingtalkclient/page/link?url=https%3A%2F%2Fh5.dingtalk.com%2Fliveeasylogin%2Findex.html%23%2Findex%3Fappid%3Ddingoaemockdlfr66612%26response_type%3Dcode%26scope%3Dsnsapi_auth%26state%3DSTATE%26redirect_uri%3Dhttp%253A%252F%252Floca77host%253A7001%252Fapi%252Ftest%252FtestCode.json%3fddtab%3dtrue

code有什麼用?

  1. 可以擷取使用者資訊;
  2. 可以擷取access_token

擷取使用者資訊

//擷取使用者資訊
        DefaultDingTalkClient client = new DefaultDingTalkClient(DingTalkConstants.URL_GET_USER_INFO_BY_CODE);
        OapiSnsGetuserinfoBycodeRequest request = new OapiSnsGetuserinfoBycodeRequest();
        request.setTmpAuthCode(requestAuthCode);
        request.setHttpMethod(HttpMethod.POST.toString());

        OapiSnsGetuserinfoBycodeResponse response;
        try {
            response = client.execute(request, dingTalkProperties.getAppid(), dingTalkProperties.getAppsecret());
        } catch (ApiException e) {
            logger.error("accessToken:{0}, url:{1}", "", DingTalkConstants.URL_GET_USER_INFO_BY_CODE, e);
            return null;
        }

        LoginedUser loginedUser = null;
        if (response.isSuccess() && null != response.getUserInfo()) {
            OapiSnsGetuserinfoBycodeResponse.UserInfo userInfo = response.getUserInfo();           

擷取access_token

參考

繼續閱讀