1. 基本認知
1.1 業務場景
A網站需要獲取B網站用戶的數據,需要跳轉到B網站,用戶登陸後授權,A網站得到一個有時效和權限的令牌(token),可以通過令牌獲取用戶的信息。
1.2 令牌與密碼的區別
-
令牌是短期的,到期會自動失效,用戶自己無法修改。密碼一般長期有效,用戶不修改,就不會發生變化。
-
令牌可以被數據所有者撤銷,會立即失效。以上例而言,屋主可以隨時取消快遞員的令牌。密碼一般不允許被他人撤銷。
-
令牌有權限範圍(scope),比如只能進小區的二號門。對於網絡服務來說,只讀令牌就比讀寫令牌更安全。密碼一般是完整權限。
2.授權方式
-
授權碼(authorization-code)
第一步,A 網站提供一個鏈接,用戶點擊後就會跳轉到 B 網站,授權用戶數據給 A 網站使用。下面就是 A 網站跳轉 B 網站的一個示意鏈接。
response_type
參數表示要求返回授權碼(code
),client_id
參數讓 B 知道是誰在請求,redirect_uri
參數是 B 接受或拒絕請求後的跳轉網址,scope
參數表示要求的授權範圍(這裏是只讀)。
第二步,用戶跳轉後,B 網站會要求用戶登錄,然後詢問是否同意給予 A 網站授權。用戶表示同意,這時 B 網站就會跳回redirect_uri
參數指定的網址。跳轉時,會傳回一個授權碼code。
第三步,A 網站拿到授權碼以後,就可以在後端,向 B 網站請求令牌。client_id
參數和client_secret
參數用來讓 B 確認 A 的身份(client_secret
參數是保密的,因此只能在後端發請求),grant_type
參數的值是AUTHORIZATION_CODE
,表示採用的授權方式是授權碼,code
參數是上一步拿到的授權碼,redirect_uri
參數是令牌頒發後的回調網址。
第四步,B 網站收到請求以後,就會頒發令牌。具體做法是向redirect_uri
指定的網址,發送一段 JSON 數據。access_token
字段就是令牌,A 網站在後端拿到了。
-
隱藏式(implicit)
有些 Web 應用是純前端應用,沒有後端。這時就不能用上面的方式了,必須將令牌儲存在前端。
第一步,A 網站提供一個鏈接,要求用戶跳轉到 B 網站,授權用戶數據給 A 網站使用。response_type
參數爲token
,表示要求直接返回令牌。
第二步,用戶跳轉到 B 網站,登錄後同意給予 A 網站授權。這時,B 網站就會跳回redirect_uri
參數指定的跳轉網址,並且把令牌作爲 URL 參數,傳給 A 網站。
-
密碼式(password)
如果你高度信任某個應用,RFC 6749 也允許用戶把用戶名和密碼,直接告訴該應用。該應用就使用你的密碼,申請令牌,這種方式稱爲"密碼式"(password)。
第一步,A 網站要求用戶提供 B 網站的用戶名和密碼。拿到以後,A 就直接向 B 請求令牌。grant_type
參數是授權方式,這裏的password
表示"密碼式",username
和password
是 B 的用戶名和密碼。
第二步,B 網站驗證身份通過後,直接給出令牌。注意,這時不需要跳轉,而是把令牌放在 JSON 數據裏面,作爲 HTTP 迴應,A 因此拿到令牌。
-
客戶端憑證(client credentials)
最後一種方式是憑證式(client credentials),適用於沒有前端的命令行應用,即在命令行下請求令牌。
第一步,A 應用在命令行向 B 發出請求。grant_type
參數等於client_credentials
表示採用憑證式,client_id
和client_secret
用來讓 B 確認 A 的身份。
第二步,B 網站驗證通過以後,直接返回令牌。
這種方式給出的令牌,是針對第三方應用的,而不是針對用戶的,即有可能多個用戶共享同一個令牌。