原文章 作者:Aaron Parecki
譯者:MoCha => 摩卡先生
前言
授權碼模式大概是我們所最常見的OAuth 2.0 授權模式。當用戶授權給App時,授權碼模式就會在網頁應用和原生apps中使用到。
本文章是本系列文章中的第一部分,我們將探討常用的OAuth 2.0 授權模式。如果你想在我們深入之前了解更多有關OAuth 2.0的知識,請查看What the Heck is OAuth?,這篇文章同樣能夠在Okta開發者博客上找到。
What is an OAuth 2.0 Grant Type? 什么是 OAuth 2.0 授權模式?
在OAuth 2.0 標準中,“授權模式”指的是一種為應用程序獲取access token的方式。
OAuth 2.0 定義了好幾種授權模式,其中包括“授權碼模式”。OAuth 2.0 的擴展同樣可以定義一些新的授權模式。
每一種授權模式在對應的一些特殊用例中都有著最佳實踐,例如:web app,原生 app,一些無法啟動web瀏覽器的設備,或者是服務器端到服務器端的應用程序。
The Authorization Code Flow 授權碼模式的流程
授權碼授權模式被用于web應用以及手機app中。與大多數授權模式不同,授權碼模式會在一開始就請求應用去啟動瀏覽器來進行一系列操作。更深入點說,授權碼模式的流程有以下步驟:
- 應用程序打開瀏覽器,將用戶連接到OAuth的服務端中
- 用戶會看到授權提示以及是否同意應用的請求
- 用戶被重定向回到應用程序中,同時在請求欄中攜帶著授權碼字符串
- 應用程序為了獲取access token而進行交換授權碼的操作
Get the User’s Permission 獲取用戶權限
OAuth 旨在讓用戶能夠授予應用程序特定的受限訪問權限。應用程序首先會確定需要請求的權限,之后會將用戶傳送至對應的瀏覽器中以獲得他們的許可。為了開啟授權流程,應用程序會構造類似以下格式的URL,并且通過瀏覽器進行訪問。
https://authorization-server.com/auth ?response_type=code &client_id=29352915982374239857 &redirect_uri=https%3A%2F%2Fexample-app.com%2Fcallback &scope=create+delete &state=xcoiv98y2kd22vusuye3kch
下面是有關請求參數的說明:
- response_type=code告訴授權服務器,應用正在初始化授權流程
- client_id 應用程序的公共標識,將在開發者首次注冊應用時獲得
- redirect_uri 告訴授權服務器當用戶同意應用的請求后應該將用戶返回到何處
- scope 一個或多個以空格分隔的字符串,用于指示應用程序請求的權限。在使用具體的OAuth API時,我們將指定所支持作用域。
- state 應用程序將生成一個隨機字符串并包含在請求中,我們應該對用戶授權應用程序后是否返回相同的值進行檢查。這是為了防止 CSRF attacks.
當用戶訪問此URL時,授權服務器會提示用戶,詢問他們是否要授權此應用程序的請求。

Redirect Back to the Application 重定向回到應用程序
如果用戶同意授權,那么授權服務器將重定向回到指定的redirect_uri ,并且攜帶著code以及state
例如,用戶將重定向回到以下URL:
https://example-app.com/redirect ?code=g0ZGZmNjVmOWIjNTk2NTk4ZTYyZGI3 &state=xcoiv98y2kd22vusuye3kch
state的值將會和應用程序剛初始請求時設置的一樣。但應用程序應當檢查重定向中的state是否與最初設置的state一致
code是通過授權服務器生成的授權碼,授權碼相對來說存活時間是短暫的,在依賴OAuth服務的情況下,一般存活在1~10分鐘。
Exchange the Authorization Code for an Access Token 為了獲取Access Token 進行的授權碼交換
我們即將要結束授權的流程啦。現在應用程序有了授權碼,我們可以用它來獲取Access Token。
應用程序將會通過以下步驟發起POST請求到服務令牌終端:
- grant_type=authorization_code 告訴令牌終端,應用程序正在使用授權碼模式。
- code 重定向回來后,應用程序所攜帶的授權碼。
- redirect_uri 與請求授權碼時設置的重定向URL一樣。有些API不需要該請求參數,所以在使用之前應當仔細查閱想要使用API的文檔。
- client_id 應用程序的客戶端ID。
- client_secret 應用程序的客戶端secret。確保獲取到access token是來自該應用程序的,而不是那些有可能攔截授權碼的潛藏攻擊者。
令牌終端將驗證請求中的所有參數,確保授權碼不會過期以及客戶端ID和客戶端secret是匹配的。如果一切的檢查順利,沒有問題,那么將會生成一個access token響應回去!
HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store Pragma: no-cache { "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3", "token_type":"bearer", "expires_in":3600, "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk", "scope":"create delete" }
這就是完整的授權流程啦!現在應用程序有了access token,那么就可以調用相關API進行請求啦。
When to use the Authorization Code Flow 什么時候該使用授權碼
在使用web應用或者是手機應用中,授權碼模式將是最好的選擇。由于授權碼模式在獲取access token上額外進行了交換授權碼的步驟,因此提供了一種隱式授權模式所沒有的安全層。
如果你正在手機應用上使用授權碼模式,或者無法存儲客戶端secret的其他任何類型應用程序,那么你應該使用PKCE extension ,它會提供可能攔截授權碼的其他攻擊的保護。
交換授權碼的步驟確保攻擊者無法攔截access token,這是因為access token總是通過應用程序與OAuth服務器之間的安全反向通道傳輸。