

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在授權碼授予中使用 PKCE
<a name="using-pkce-in-authorization-code"></a>

Amazon Cognito 在授權碼授予中支援 Code Exchange (PKCE) 身分驗證的驗證金鑰。PKCE 是公有用戶端 2.0 OAuth 授權碼授予的延伸。PKCE 可防止兌換攔截的授權碼。

## Amazon Cognito 如何使用 PKCE
<a name="how-pkce-works"></a>

若要開始使用 PKCE 進行身分驗證，您的應用程式必須產生唯一的字串值。此字串是程式碼驗證器，Amazon Cognito 用來將請求初始授權的用戶端與交換權杖授權碼的用戶端進行比較的秘密值。

您的應用程式必須將 SHA256 雜湊套用至程式碼驗證器字串，並將結果編碼為 base64。將雜湊字串傳遞至 [授權端點](authorization-endpoint.md)做為請求內文中的`code_challenge`參數。當您的應用程式交換權杖的授權碼時，它必須以純文字包含程式碼驗證器字串，做為 請求內文中的`code_verifier`參數[權杖端點](token-endpoint.md)。Amazon Cognito 會在程式碼驗證器上執行相同的hash-and-encode操作。Amazon Cognito 只會在判斷程式碼驗證器產生與授權請求中收到相同的程式碼挑戰時，才會傳回 ID、存取和重新整理權杖。

**使用 PKCE 實作授權授予流程**

1. 開啟 Amazon Cognito [主控台](https://console.aws.amazon.com/cognito/home)。如果出現提示，請輸入您的 AWS 登入資料。

1. 選擇 **User Pools** (使用者集區)。

1. 從清單中選擇現有的使用者集區，或建立使用者集區。如果您建立使用者集區，系統會提示您在精靈期間設定應用程式用戶端和設定受管登入。

   1. 如果您建立新的使用者集區，請設定應用程式用戶端，並在引導式設定期間設定受管登入。

   1. 如果您設定現有的使用者集區，如果您尚未新增[網域](cognito-user-pools-assign-domain.md)和[公有應用程式用戶端](user-pool-settings-client-apps.md)。

1. 產生隨機英數字串，通常是全域唯一識別符 ([UUID](cognito-terms.md#terms-uuid))，以為 PKCE 建立程式碼挑戰。此字串是您將在請求中提交至 的 `code_verifier` 參數值[權杖端點](token-endpoint.md)。

1. 使用 SHA256 演算法雜湊`code_verifier`字串。將雜湊操作的結果編碼至 base64。此字串是您將在請求中提交至 的 `code_challenge` 參數值[授權端點](authorization-endpoint.md)。

   下列Python範例會產生 `code_verifier`並計算 `code_challenge`：

   ```
   #!/usr/bin/env python3
   
   import secrets
   from base64 import urlsafe_b64encode
   from hashlib import sha256
   from string import ascii_letters
   from string import digits
   
   # use the secrets module for cryptographically strong random values
   alphabet = ascii_letters + digits
   code_verifier = ''.join(secrets.choice(alphabet) for _ in range(128))
   code_verifier_hash = sha256(code_verifier.encode()).digest()
   code_challenge = urlsafe_b64encode(code_verifier_hash).decode().rstrip('=')
   
   print(f"code challenge: {code_challenge}")
   print(f"code verifier: {code_verifier}")
   ```

   以下是來自Python指令碼的範例輸出：

   ```
   code challenge: Eh0mg-OZv7BAyo-tdv_vYamx1boOYDulDklyXoMDtLg
   code verifier: 9D-aW_iygXrgQcWJd0y0tNVMPSXSChIc2xceDhvYVdGLCBk-JWFTmBNjvKSdOrjTTYazOFbUmrFERrjWx6oKtK2b6z_x4_gHBDlr4K1mRFGyE8yA-05-_v7Dxf3EIYJH
   ```

1. 使用 PKCE 完成具有授權碼授予請求的受管登入。以下是 URL 範例：

   ```
   https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?response_type=code&client_id=1example23456789&redirect_uri=https://www.example.com&code_challenge=Eh0mg-OZv7BAyo-tdv_vYamx1boOYDulDklyXoMDtLg&code_challenge_method=S256
   ```

1. 收集授權`code`，並使用權杖端點將其兌換為權杖。以下是範例請求：

   ```
   POST /oauth2/token HTTP/1.1
   Host: mydomain.auth.us-east-1.amazoncognito.com
   Content-Type: application/x-www-form-urlencoded
   Content-Length: 296
   
   redirect_uri=https%3A%2F%2Fwww.example.com&
   client_id=1example23456789&
   code=7378f445-c87f-400c-855e-0297d072ff03&
   grant_type=authorization_code&
   code_verifier=9D-aW_iygXrgQcWJd0y0tNVMPSXSChIc2xceDhvYVdGLCBk-JWFTmBNjvKSdOrjTTYazOFbUmrFERrjWx6oKtK2b6z_x4_gHBDlr4K1mRFGyE8yA-05-_v7Dxf3EIYJH
   ```

1. 檢閱回應。它將包含 ID、存取和重新整理權杖。如需使用 Amazon Cognito 使用者集區字符的詳細資訊，請參閱 [了解使用者集區 JSON Web 字符 JWTs)](amazon-cognito-user-pools-using-tokens-with-identity-providers.md)。