保護 API 資源以實現機器對機器的通信
學習如何利用 OAuth 2.0 和 JWT 來保護你的 API 資源,以實現機器對機器的通信。
構建涉及多個服務的項目時,API 資源的安全性是一個關鍵問題。在本文中,我將向你展示如何利用 OAuth 2.0 和 JWT 來保護服務之間的通信(機器對機器),以及如何應用基於角色的訪問控制(RBAC)以遵循最低權限原則。
開始使用
為了便於學習,我假設你擁有以下先決條件:
- 一個 Logto Cloud 帳號,或自行托管的 Logto 實例
- 至少兩個需要相互通信的服務
出於演示目的,我們假設擁有以下服務:
- 一個提供 API 用於管理購物車的購物車服務
- 端點:
https://cart.example.com/api
- 端點:
- 一個提供 API 用於處理支付的支付服務
- 端點:
https://payment.example.com/api
- 端點:
驗證流程
現在,我們的購物車服務需要調用支付服務以處理支付。驗證流程如下:
上圖中一些關鍵概念:
- JWT (RFC 7519):JSON Web Token。參見我們的上一篇文章,瞭解 JWT 的介紹。
- JWK (RFC 7517):JSON Web Key 用於驗證 JWT 的簽名。JWK 集是 JWK 的集合。
- "client_credentials" 授權 (RFC 6749):OAuth 2.0 中的一種授權類型。使用客戶端的憑據來獲取訪問令牌。我們會在後面的部分展示詳情。
以上圖中的每個參與者在驗證流程中都有其角色:
- 購物車服務:需要調用支付服務的客戶端。雖然它是一個服務,但在 OAuth 2.0 的上下文中,它仍然是客戶端,我們在 Logto 中稱這樣的客戶端為"機器對機器應用程序"。
- Logto:發放訪問令牌的 OAuth 2.0 授權服務器。
- 支付服務:提供 API 用於處理支付的 API 資源。
讓我們一步一步地了解驗證流程。
初始設置
要執行驗證流程,我們需要在 Logto 中創建一個機器對機器應用程序(購物車服務)和一個 API 資源(支付服務)。
創建 API 資源
由於我們的購物車服務在執行驗證時需要知道支付服務的 API,因此我們需要首先創建一個 API 資源。進入 Logto 控制台,點擊左側邊欄中的 API 資源,然後點擊 創建 API 資源。在開啟的對話框中,我們提供了一些教程幫助你開始使用。你也可以點擊 繼續而不使用 教程 以跳過它。
輸入 API 名稱和標識符,例如 Payment service
和 https://payment.example.com/api
,然後點擊 創建 API 資源。
創建 API 資源後,你會被重定向到詳細信息頁面。現在我們可以暫時不處理它。
創建機器對機器應用程序
點擊左側邊欄中的 應用程序,然後點擊 創建應用程序。在開啟的對話框中,找到 機器對機器 卡片,然後點擊 開始構建。
輸入應用程序名稱,例如 Cart service
,然後點擊 創建應用程序。將顯示一個互動指南來幫助你設置應用程序。你可以按照指南瞭解基本用法,或者點擊 完成並完成 以跳過它。
請求訪問令牌
由於假設機器對機器應用程序是安全的(例如,它們部署在私有網絡中),因此我們可以使用 OAuth 2.0 "client_credentials" 授權來獲得訪問令牌。它使用基本身份驗證來驗證客戶端:
- 請求 URL 是你的 Logto 實例的令牌端點。你可以在機器對機器應用程序詳細信息頁面的 高級設置 標籤中找到並複製它。
- 請求方法是
POST
。 - 請求
Content-Type
標頭是application/x-www-form-urlencoded
。 - 對於
Authorization
標頭,值是Basic <base64(app_id:app_secret)>
,其中app_id
和app_secret
是機器對機器應用程序的應用程序 ID 和應用程序密鑰。你可以在應用程序詳細信息頁面中找到它們。 - 請求主體需要指定授權類型和 API 標識符。例如,
grant_type=client_credentials&resource=https://payment.example.com/api
。grant_type=client_credentials
:"client_credentials" 授權的固定值。resource=https://payment.example.com/api
:客戶端希望訪問 API 資源的 API 標識符。- 如果應用程序需要通過範圍(權限)授權,你還可以在請求主體中指定範圍。例如,
scope=read:payment write:payment
。我們將在後面講述範圍。
以下是使用 curl
的請求示例:
成功的響應主體可能是:
使用授權標頭發送請求
現在我們有了訪問令牌,我們可以將其附加到請求發到 API 資源時的 Authorization
標頭中。例如,如果我們想調用支付服務的 POST /payments
API,我們可以發送以下請求: