
OAuth 2.0 快速指南
OAuth 2.0 - 概述
什麼是 OAuth 2.0?
OAuth 是一種開放的授權協議,它允許客戶端應用程式訪問資源所有者的資源,方法是啟用諸如 Facebook、GitHub 等 HTTP 服務上的客戶端應用程式。它允許在不使用其憑據的情況下將儲存在一個站點上的資源共享到另一個站點。它使用使用者名稱和密碼令牌代替。
OAuth 2.0 由 *IETF OAuth 工作組* 開發,於 2012 年 10 月釋出。
為什麼要使用 OAuth 2.0?
您可以使用 OAuth 2.0 從另一個應用程式讀取使用者的資料。
它為 Web、桌面應用程式和移動裝置提供授權工作流程。
它是一個使用授權碼的伺服器端 Web 應用,並且不與使用者憑據互動。
OAuth 2.0 的特性
OAuth 2.0 是一種簡單的協議,允許訪問使用者的資源而無需共享密碼。
它為使用指令碼語言(如 JavaScript)執行客戶端應用程式提供使用者代理流程。通常,瀏覽器是使用者代理。
它使用令牌而不是使用其憑據來訪問資料,並將資料儲存在使用者的線上檔案系統中,例如 Google Docs 或 Dropbox 帳戶。
OAuth 2.0 的優勢
OAuth 2.0 是一種非常靈活的協議,它依賴於 SSL(確保 Web 伺服器和瀏覽器之間的資料保持私密的安全套接字層)來儲存使用者訪問令牌。
OAuth 2.0 依賴於 SSL,SSL 用於確保加密行業協議,並用於確保資料安全。
它允許有限地訪問使用者的資料,並在授權令牌過期時允許訪問。
它能夠在無需釋出個人資訊的情況下為使用者共享資料。
它更容易實現並提供更強大的身份驗證。
OAuth 2.0 的缺點
如果您在規範的末尾新增更多擴充套件,它將產生範圍廣泛的互操作性實現,這意味著您必須為 Facebook、Google 等編寫單獨的程式碼段。
如果您的收藏網站連線到中央樞紐,並且中央帳戶被駭客入侵,那麼它將導致多個網站而不是僅僅一個網站受到嚴重影響。
OAuth 2.0 - 架構
在本章中,我們將討論 OAuth 2.0 的架構風格。

**步驟 1** - 首先,使用者使用客戶端應用程式(例如 Google、Facebook、Twitter 等)訪問資源。
**步驟 2** - 接下來,在註冊重定向 URI(統一資源識別符號)期間,將向客戶端應用程式提供客戶端 ID 和客戶端密碼。
**步驟 3** - 使用者使用身份驗證應用程式登入。客戶端 ID 和客戶端密碼對於授權伺服器上的客戶端應用程式是唯一的。
**步驟 4** - 身份驗證伺服器使用授權碼將使用者重定向到重定向統一資源識別符號 (URI)。
**步驟 5** - 使用者訪問客戶端應用程式中重定向 URI 處的頁面。
**步驟 6** - 將向客戶端應用程式提供身份驗證程式碼、客戶端 ID 和客戶端密碼,並將它們傳送到授權伺服器。
**步驟 7** - 身份驗證應用程式將訪問令牌返回給客戶端應用程式。
**步驟 8** - 一旦客戶端應用程式獲得訪問令牌,使用者就開始使用客戶端應用程式訪問資源所有者的資源。
OAuth 2.0 有各種概念,在下表中簡要解釋。
序號 | 概念及描述 |
---|---|
1 | 術語
OAuth 提供了一些額外的術語來理解授權的概念。 |
2 | Web 伺服器
Web 伺服器提供網頁並使用 HTTP 為使用者提供構成網頁的檔案。 |
3 | 使用者代理
使用者代理應用程式由使用者裝置中的客戶端應用程式使用,充當指令碼語言例項。 |
4 | 原生應用程式
原生應用程式可以用作桌面或手機應用程式的例項,它使用資源所有者密碼憑據。 |
OAuth 2.0 - 客戶端憑據
當客戶端是資源所有者時,或者當授權範圍僅限於客戶端控制下的受保護資源時,可以使用客戶端憑據作為授權授予。
客戶端僅在客戶端憑據的幫助下請求訪問令牌。
客戶端憑據授權流程用於獲取訪問令牌以授權 API 請求。
使用客戶端憑據授權,獲取的訪問令牌僅授予您的客戶端應用程式搜尋和獲取目錄文件的許可權。
下圖描繪了客戶端憑據流程。

上圖所示的流程包含以下步驟 -
**步驟 1** - 客戶端向授權伺服器進行身份驗證,並向令牌端點請求訪問令牌。
**步驟 2** - 授權伺服器對客戶端進行身份驗證,如果客戶端有效且已授權,則提供訪問令牌。
下表列出了客戶端憑據的概念。
序號 | 概念及描述 |
---|---|
1 | 獲取終端使用者授權
授權端點通常是授權伺服器上的 URI,資源所有者在其中登入並允許客戶端應用程式訪問資料。 |
2 | 授權響應
授權響應可用於獲取訪問令牌,以使用授權碼訪問系統中的所有者資源。 |
3 | 錯誤響應和程式碼
如果在授權期間發生錯誤,授權伺服器將以 HTTP 400 或 401(錯誤請求)狀態碼進行響應。 |
OAuth 2.0 - 獲取訪問令牌
訪問令牌是識別使用者、應用程式或頁面的字串。令牌包含諸如令牌何時過期以及建立該令牌的應用程式等資訊。
首先,有必要從 API 控制檯獲取 OAuth 2.0 客戶端憑據。
然後,客戶端向授權伺服器請求訪問令牌。
它從響應中獲取訪問令牌,並將令牌傳送到您希望訪問的 API。
您必須首先將使用者傳送到授權端點。以下是一個虛擬請求的示例
https://publicapi.example.com/oauth2/authorize?client_id=your_client_id&redirect_uri=your_url &response_type=code
以下是引數及其描述。
**client_id** - 應設定為應用程式的客戶端 ID。
**redirect_uri** - 應設定為 URL。授權請求後,使用者將被重定向回。
**response_type** - 可以是程式碼或令牌。程式碼必須用於伺服器端應用程式,而令牌必須用於客戶端應用程式。在伺服器端應用程式中,您可以確保安全地儲存機密。
下表列出了客戶端憑據的概念。
序號 | 概念及描述 |
---|---|
1 | 授權碼
授權碼允許訪問授權請求,並允許客戶端應用程式獲取所有者資源。 |
2 | 資源所有者密碼憑據
資源所有者密碼憑據僅包含一個請求和一個響應,在資源所有者與客戶端關係良好的情況下很有用。 |
3 | 斷言
斷言是資訊包,它使跨各種安全域共享身份和安全資訊成為可能。 |
4 | 重新整理令牌
重新整理令牌用於獲取新的訪問令牌,其中包含獲取新訪問令牌所需的資訊。 |
5 | 訪問令牌響應
訪問令牌是由授權伺服器分配的一種令牌。 |
6 | 訪問令牌錯誤響應程式碼
如果授權伺服器發出的令牌訪問請求無效或未經授權,則授權伺服器將返回錯誤響應。 |
OAuth 2.0 - 訪問受保護的資源
客戶端向資源伺服器提供訪問令牌以訪問受保護的資源。資源伺服器必須驗證並確認訪問令牌有效且未過期。
有兩種標準的傳送憑據方式 -
**承載令牌** - 訪問令牌只能放置在 POST 請求正文中或作為授權 HTTP 標頭中的後備選項的 GET URL 引數中。
它們包含在授權標頭中,如下所示 -
Authorization: Bearer [token-value]
例如 -
GET/resource/1 HTTP /1.1 Host: example.com Authorization: Bearer abc...
**MAC** - 使用請求的元素計算加密**訊息認證碼**(MAC),並將其傳送到授權標頭。收到請求後,資源所有者會比較並計算 MAC。
下表顯示了訪問受保護資源的概念。
序號 | 概念及描述 |
---|---|
1 | 已認證請求
它用於獲取授權碼令牌以訪問系統中的所有者資源。 |
2 | WWW-Authenticate 響應標頭欄位
如果受保護的資源請求包含無效的訪問令牌,則資源伺服器將包含“WWW-Authenticate”響應標頭欄位。 |
OAuth 2.0 - 可擴充套件性
可以定義訪問令牌型別的兩種方式 -
透過在訪問令牌型別的登錄檔中註冊。
透過使用唯一的絕對 URI(統一資源識別符號)作為其名稱。
定義新的端點引數
引數名稱必須遵守 param-name ABNF(增強巴克斯-諾爾正規化是一種基於巴克斯-諾爾正規化的元語言,包含其自身的語法和派生規則),並且引數值的語法必須定義明確。
param-name = 1* name-char name-char = "-" / "." / "_" / DIGIT / ALPHA
定義新的授權授予型別
可以使用“grant_type”引數為新的授權授予型別分配一個不同的絕對 URI 以供使用。如果擴充套件授權授予型別需要其他令牌端點引數,則必須在 OAuth 引數登錄檔中註冊。
定義新的授權端點響應型別
response-type = response-name *(SP response-name) response-name = 1* response-char response-char = "_" / DIGIT / ALPHA
如果響應型別具有一個或多個空格字元,則將其作為以空格分隔的值列表進行比較,其中值的順序無關緊要,並且只能註冊一個值的順序。
定義其他錯誤程式碼
如果它們使用的副檔名是已註冊的訪問令牌或已註冊的端點引數,則必須註冊擴充套件錯誤程式碼。錯誤程式碼必須遵守 error ABNF(增強巴克斯-諾爾正規化),並且在可能的情況下,它應該以識別它的名稱作為字首。
error = 1 * error_char error-char = %x20-21 / %x23-5B / 5D-7E
OAuth 2.0 - IANA 注意事項
IANA 代表**I**nternet **A**ssigned **N**umbers **A**uthority,它提供有關與**R**emote **A**uthentication **D**ial **I**n **U**ser **S**ervice (RADIUS) 相關的註冊值的資訊。
IANA 包括以下注意事項 -
OAuth 訪問令牌型別登錄檔
OAuth 訪問令牌由專家根據所需的規範進行註冊。如果他們對註冊結果滿意,才會釋出規範。註冊請求將傳送至 @ietf.org 進行審查,主題為“訪問令牌型別請求:示例”。專家將在請求發出後的 14 天內拒絕或接受請求。
註冊模板
註冊模板包含以下規範:
型別名稱 - 它是請求的名稱。
令牌端點響應引數 - 額外的訪問令牌響應引數將在 OAuth 引數登錄檔中單獨註冊。
HTTP 身份驗證方案 - HTTP 身份驗證方案可用於使用訪問令牌對資源進行身份驗證。
變更控制者 - 對於標準跟蹤 RFC,請將狀態名稱指定為“IETF”,對於其他情況,請使用負責方的名稱。
規範文件 - 規範文件包含可用於檢索文件副本的引數。
OAuth 引數登錄檔
OAuth 引數登錄檔包含專家根據所需規範對授權端點請求或響應、令牌端點請求或響應進行的註冊。註冊請求將傳送給專家,如果他們對註冊結果滿意,則會發布規範。
註冊模板
註冊模板包含諸如型別名稱、變更控制者和規範文件之類的規範,其定義與上述OAuth 訪問令牌型別登錄檔部分相同,但以下規範除外:
引數使用位置 - 它指定引數的位置,例如授權請求或響應、令牌請求或響應。
初始登錄檔內容
下表顯示了包含初始內容的 OAuth 引數登錄檔:
序號 | 引數名稱和使用位置 | 變更控制者 | 規範文件 |
---|---|---|---|
1 | client_id 授權請求、令牌請求 |
IETF | RFC 6749 |
2 | client_secret 令牌請求 |
IETF | RFC 6749 |
3 | response_type 授權請求 |
IETF | RFC 6749 |
4 | redirect_uri 授權請求、授權 |
IETF | RFC 6749 |
5 | scope 授權請求或響應、令牌請求或響應 |
IETF | RFC 6749 |
6 | state 授權請求或響應 |
IETF | RFC 6749 |
7 | code 令牌請求、授權響應 |
IETF | RFC 6749 |
8 | error_description 授權響應、令牌響應 |
IETF | RFC 6749 |
9 | error_uri 授權響應、令牌響應 |
IETF | RFC 6749 |
10 | grant_type 令牌請求 |
IETF | RFC 6749 |
11 | access_token 授權響應、令牌響應 |
IETF | RFC 6749 |
12 | token_type 授權響應、令牌響應 |
IETF | RFC 6749 |
13 | expires_in 授權響應、令牌響應 |
IETF | RFC 6749 |
14 | username 令牌請求 |
IETF | RFC 6749 |
15 | password 令牌請求 |
IETF | RFC 6749 |
16 | refresh_token 令牌請求、令牌響應 |
IETF | RFC 6749 |
OAuth 授權端點響應型別登錄檔
這可用於定義 OAuth 授權端點響應型別登錄檔。響應型別由專家根據所需的規範進行註冊,如果他們對註冊結果滿意,才會釋出規範。註冊請求將傳送至 @ietf.org 進行審查。專家將在請求發出後的 14 天內拒絕或接受請求。
註冊模板
註冊模板包含諸如型別名稱、變更控制者和規範文件之類的規範,其定義與上述OAuth 訪問令牌型別登錄檔部分相同。
初始登錄檔內容
下表顯示了包含初始內容的授權端點響應型別登錄檔。
OAuth 擴充套件錯誤登錄檔
這可用於定義 OAuth 擴充套件錯誤登錄檔。錯誤程式碼以及協議擴充套件(例如授權型別、令牌型別等)由專家根據所需的規範進行註冊。如果他們對註冊結果滿意,才會釋出規範。註冊請求將傳送至 @ietf.org 進行審查,主題為“錯誤程式碼請求:示例”。專家將在請求發出後的 14 天內拒絕或接受請求。
註冊模板
註冊模板包含諸如變更控制者和規範文件之類的規範,其定義與上述OAuth 訪問令牌型別登錄檔部分相同,但以下規範除外:
錯誤名稱 - 它是請求的名稱。
錯誤使用位置 - 它指定錯誤的位置,例如授權碼授予錯誤響應、隱式授予響應或令牌錯誤響應等,指定錯誤可以使用的位置。
相關協議擴充套件 - 可以使用協議擴充套件,例如擴充套件授權型別、訪問令牌型別、擴充套件引數等。