Client Credentials Grant
Client Credentials Grant 由 RFC 6749 Section 4.4 定義,是 OAuth 2.0 中最單純的授權流程。整個過程不涉及使用者,Client 直接以自己的憑證換取 Access Token。
解決什麼問題
Section titled “解決什麼問題”在許多場景中,需要存取受保護資源的不是「使用者」而是「應用程式本身」:
- 後端服務對服務——微服務架構中,服務 A 需要呼叫服務 B 的 API
- 排程任務——定時執行的批次程式需要存取 API
- 跨系統 API 串接——例如代購商家的系統串接電商平台的 API
這些場景的共通點是沒有使用者參與授權流程。使用 Authorization Code Flow 不合適,因為沒有人可以在瀏覽器中登入並點選「同意」。
Client Credentials Grant 的解法很直覺:Client 本身就是資源的請求者,直接用自己的憑證(client_id + client_secret)向 Authorization Server 證明身分,取得 Access Token。
sequenceDiagram
participant Client as Client(後端服務)
participant AS as Authorization Server
participant RS as Resource Server
Client->>AS: 1. Token Request(client_id + client_secret)
AS->>AS: 2. 驗證 Client 身分
AS->>Client: 3. 核發 Access Token
Client->>RS: 4. 使用 Access Token 存取資源
RS->>Client: 5. 回傳資源
Step 1:Token Request
Section titled “Step 1:Token Request”Client 向 Authorization Server 的 Token Endpoint 發送請求,以 HTTP Basic Authentication 提供 Client 憑證:
POST /token HTTP/1.1Host: auth.example.comAuthorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWContent-Type: application/x-www-form-urlencoded
grant_type=client_credentials&scope=read:orders| 參數 | 必要性 | 說明 |
|---|---|---|
grant_type | REQUIRED | 固定值 client_credentials |
scope | OPTIONAL | 申請的授權範圍 |
Client 認證方式通常是以下兩種之一:
client_secret_basic(推薦)——將client_id:client_secret做 Base64 編碼放在Authorizationheaderclient_secret_post——將client_id和client_secret放在 request body
Step 2:Token Response
Section titled “Step 2:Token Response”Authorization Server 驗證 Client 身分後,核發 Access Token:
{ "access_token": "eyJhbGciOiJSUzI1NiJ9...", "token_type": "Bearer", "expires_in": 3600, "scope": "read:orders"}注意回應中不包含 refresh_token。因為 Client 持有 client_secret,隨時可以重新發送 Token Request 取得新的 Access Token,不需要透過 Refresh Token 來延長授權。
Step 3:使用 Access Token
Section titled “Step 3:使用 Access Token”Client 以 Authorization: Bearer header 存取 Resource Server:
GET /api/orders HTTP/1.1Host: api.example.comAuthorization: Bearer eyJhbGciOiJSUzI1NiJ9...簡單但適用範圍受限
Section titled “簡單但適用範圍受限”Client Credentials Grant 是所有 Grant Type 中最簡單的——只需要一次 Token Request。但它的代價是完全沒有使用者參與,無法取得「代表某個使用者」的 Access Token。如果需要存取特定使用者的資源,應改用 Authorization Code Flow。
不核發 Refresh Token
Section titled “不核發 Refresh Token”RFC 6749 建議 Authorization Server 不應在 Client Credentials Grant 中核發 Refresh Token。原因是 Client 本身就持有 client_secret,重新請求 Token 的成本很低,不需要額外的 Refresh Token 機制。
與 API Key 的差異
Section titled “與 API Key 的差異”Client Credentials Grant 乍看之下跟直接使用 API Key 很像,但有幾個重要差異:
- Token 有時效性——Access Token 會過期,即使洩漏損害也有時間限制;API Key 通常長期有效
- Scope 控制——每次請求可以指定不同的授權範圍;API Key 通常是固定權限
- 標準化——遵循 OAuth 2.0 標準,與其他 OAuth 流程共用基礎設施(Token Endpoint、Token 驗證機制等)
Client 認證的安全性
Section titled “Client 認證的安全性”Client Credentials Grant 只適用於 Confidential Client——能夠安全保管 client_secret 的應用程式(通常是後端服務)。如果 client_secret 無法安全保管(例如行動 App 或前端應用),就不應該使用這個流程。
client_secret_basic(HTTP Basic Authentication)是推薦的認證方式,因為 client_secret 放在 header 中,不會出現在 request body 或 server log 中。
TLS 保護
Section titled “TLS 保護”Token Request 包含 client_secret,必須透過 TLS 加密傳輸。沒有 TLS 的情況下,client_secret 會以明文暴露在網路上。
Scope 最小權限
Section titled “Scope 最小權限”Client 應只申請完成任務所需的最小 Scope。Authorization Server 也應限制每個 Client 可申請的 Scope 範圍,避免單一 Client 取得過大的權限。