印象中工做以來還歷來沒搞過一次 OAuth2 的接入- -,彷佛只停留在愉快的使用階段。好比如今不少網站都接了 wx 二維碼掃碼登陸或者微博登陸。因此一直只是享受着這樣的便利,卻沒有機會本身來搞一搞把裏面的技術細節打通。html
首先找到 阮一峯老師的一篇古老的文章介紹了一下 OAuth 協議。c#
歸根到底 OAuth 要作的事情就是在沒有完整用戶用戶密碼的狀況下,經過用戶受權訪問第三方本來提供給用戶的服務。後端
好比我要去上知乎,可是我不想註冊一個知乎的帳號,經過 OAuth 我能夠經過微博的帳號去訪問知乎,可是注意這裏有一點不太同樣,就是當你這麼作的時候,一般第三方服務商都會將你 OAuth 的帳號和他們平臺上的自動建立的帳號進行綁定,這樣能對你的身份進行確認。這是如今最普遍的用法,還有一種就是隻經過你的受權去訪問第三方的有限的服務。api
RFC 6749 標準 OAuth2 流程以下:服務器
(A)用戶打開客戶端之後,客戶端要求用戶給予受權。app
(B)用戶贊成給予客戶端受權。網站
(C)客戶端使用上一步得到的受權,向認證服務器申請令牌。ui
(D)認證服務器對客戶端進行認證之後,確認無誤,贊成發放令牌。url
(E)客戶端使用令牌,向資源服務器申請獲取資源。spa
(F)資源服務器確認令牌無誤,贊成向客戶端開放資源。
一般流程 B 有不少種實現的方法,我這裏看了好幾家的文檔 最經常使用的應該是受權碼模式。
可能由於受權碼是最完整,流程最嚴密的受權模式。它的特色就是經過客戶端的後臺服務器與服務提供商的認證服務器進行互動。
(A)用戶訪問客戶端,後者將前者導向認證服務器。
(B)用戶選擇是否給予客戶端受權。
(C)假設用戶給予受權,認證服務器將用戶導向客戶端事先指定的"重定向URI"(redirection URI),同時附上一個受權碼。
(D)客戶端收到受權碼,附上早先的"重定向URI",向認證服務器申請令牌。這一步是在客戶端的後臺的服務器上完成的,對用戶不可見。
(E)認證服務器覈對了受權碼和重定向URI,確認無誤後,向客戶端發送訪問令牌(access token)和更新令牌(refresh token)。
一個標準的協議在 A 步驟中包含了
response_type:上面談到的受權類型,因爲是受權碼因此這裏是 "code"
client_id: 標示客戶端的應用id
redirect_uri:驗證經過以後須要重定向到的 URI 一般會進行 url encode
scope:表示申請權限的範圍。
一個拼好的正常的 url 可能會長這樣
https://oapi.ggsimida.com/connect/qrconnect?client_id=xxx&response_type=code&scope=snsapi_login&
state=STATE&redirect_uri=http%3A//uisensor.hundun.cn/dashboard/
一般訪問該地址以後咱們會被帶到第三方受權公司的認證服務器,要求用戶進行受權。用戶經過 qrcode 或者帳號密碼登陸進行受權以後,會重定向到上面的 redirect_uri 填寫的地址而且帶上第三方應用發放的 state 和 受權權碼。
這個時候就到了 D 步驟,D 步驟經過這個受權碼,並附上重定向 URI 像第三方服務器的鑑權系統申請臨時訪問令牌,而後認證服務器覈對信息以後發放 ac令牌和 rr更新令牌,到此便完成了認證。
這裏要多說一句的是,dingding 的文檔上好像並非提供的標準 OAuth2 協議,雖然看上去很像可是並非標準的。包括上面 A 步驟的連接裏,dingding 需求一個叫 appId 的東西來替代 client_id ,而且當咱們得到受權碼以後,便無需再請求 token ,而是直接使用受權碼+應用id+應用密鑰看成身份就可直接經過接口認證請求用戶信息了。
若是使用的服務是隻支持標準的 OAuth2 協議的話,彷佛沒法無縫切換 dingding 的這個服務。
可是總有解決辦法,個人選擇是經過後端服務器包一層,將整個 OAuth2 的標準流程方在包裝層,而後由包裝層和 dingding 服務器進行交互,這樣也能實現。
Reference:
http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
https://ding-doc.dingtalk.com/doc#/serverapi3/mrugr3 dingding 二維碼登陸文檔
https://www.sensorsdata.cn/_manual/oauth_client.html sensors 標準 OAuth 文檔