最近的項目需要用到OAuth2.0認證,總結一下最常用的授權碼方式。
參考網址:
http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
https://www.cnblogs.com/kaleidoscope/p/9507261.html
第一步:請求授權碼
A網站提供連接,用戶點擊后跳轉到B網站,此時會授權用戶數據給A網站使用。
https://b.com/oauth/authorize? response_type=code& client_id=CLIENT_ID& redirect_uri=CALLBACK_URL& scope=read& state=xyz
response_type:授權類型,必選,固定“code”,表示要求返回授權碼。
client_id:客戶端id,必選,表示請求方是誰。
redirece_uri:重定向uri,可選,表示B處理請求后的跳轉網址。
scope:申請的權限范圍,可選,這里用的只讀。
state:客戶端當前狀態,可選,可以指定任意值,B會原封不動返回這個值。
第二步:返回授權碼
用戶跳轉到B網站后,網站會要求用戶登錄,然后詢問是否同意給予 A 網站授權。用戶表示同意,此時,B網站就會跳到redirece_uri參數指定的網址。跳轉時,會傳遞一個授權碼
https://a.com/callback?code=AUTHORIZATION_CODE
code:表示授權碼
第三步:請求令牌
A網站得到B傳遞的授權碼,就可以在后端,向B網站請求令牌。
https://b.com/oauth/token?
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=CALLBACK_URL
client_id:同第一步,為客戶端id,必選,表示身份。
client_secret:客戶端秘鑰,可選,為保密數據,因此只能是在后端發請求。
grant_type:授權方式,必選,表示采用的授權方式,authorization_code為授權碼方式。
-
authorization_code — 授權碼模式(即先登錄獲取code,再獲取token)
-
password — 密碼模式(將用戶名,密碼傳過去,直接獲取token)
-
client_credentials — 客戶端模式(無用戶,用戶向客戶端注冊,然后客戶端以自己的名義向’服務端’獲取資源)
-
implicit — 簡化模式(在redirect_uri 的Hash傳遞token; Auth客戶端運行在瀏覽器中,如JS,Flash)
-
refresh_token — 刷新access_token
code:授權碼,必選,傳遞第二步得到的授權碼。
redirect_uri:回調網址,必選,表示令牌頒發后的回調網址。
第四步:頒發令牌
B網站收到請求后,校驗授權碼無誤,就會頒發令牌,向第三步的redirect_uri指定的網址,發送一段JSON數據。
{
"access_token":"ACCESS_TOKEN",
"token_type":"bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN",
"scope":"read",
"uid":100101,
"info":{...}
}
access_token:頒發的令牌。
token_type:表示令牌的類型。bearer或者mac
expires_in:過期時間,單位為秒,如果省略該參數,必須以其他方式設置過期時間。
refresh_token:更新令牌,可選,用來獲取下一次的訪問令牌。
scope:權限范圍,如果與第一步的權限相同,可省略。
------
令牌的使用
A 網站拿到令牌以后,就可以向 B 網站的 API 請求數據了。
此時,每個發到 API 的請求,都必須帶有令牌。具體做法是在請求的頭信息,加上一個`Authorization`字段,令牌就放在這個字段里面。
curl -H "Authorization: Bearer ACCESS_TOKEN" \
"https://api.b.com"
ACCESS_TOKEN:拿到的令牌。
------
更新令牌
OAuth 2.0 允許用戶自動更新令牌。令牌到期時
具體方法是,B 網站頒發令牌的時候,一次性頒發兩個令牌,一個用於獲取數據,另一個用於獲取新的令牌(refresh token 字段)。令牌到期前,用戶使用 refresh token 發一個請求,去更新令牌。
https://b.com/oauth/token?
grant_type=refresh_token&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
refresh_token=REFRESH_TOKEN
grant_type:refresh_token表示要求更新令牌。
client_id & client_secret:確認身份。
refresh_token:用於更新令牌的令牌。