

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

# 整合 REST API 與 Amazon Cognito 使用者集區
<a name="apigateway-enable-cognito-user-pool"></a>

建立 Amazon Cognito 使用者集區後，您必須在 API Gateway 中建立使用該使用者集區的 `COGNITO_USER_POOLS` 授權方。下列程序示範如何使用 API Gateway 主控台來執行此操作。

**注意**  
您可以使用 [https://docs.aws.amazon.com/apigateway/latest/api/API_CreateAuthorizer.html](https://docs.aws.amazon.com/apigateway/latest/api/API_CreateAuthorizer.html) 動作來建立使用多個使用者集區的 `COGNITO_USER_POOLS` 授權者。一個 `COGNITO_USER_POOLS` 授權者最多可以使用 1,000 個使用者集區。此限制無法提高。

**重要**  
執行下列任何程序之後，您需要部署或重新部署您的 API 以傳播變更。如需部署 API 的詳細資訊，請參閱 [在 API Gateway 中部署 REST API](how-to-deploy-api.md)。

**使用 API Gateway 主控台建立 `COGNITO_USER_POOLS` 授權方**

1. 在 API Gateway 中建立新的 API 或選取現有的 API。

1. 在主導覽窗格中，選擇**授權方**。

1. 選擇**建立授權方**。

1. 若要設定新的授權方使用使用者集區，請執行下列操作：

   1.  針對**授權方名稱**，輸入名稱。

   1. 針對**授權方類型**，選取 **Cognito**。

   1. 針對 **Cognito 使用者集區**，選擇您建立 Amazon Cognito AWS 區域 的 ，然後選取可用的使用者集區。

      您可以使用階段變數來定義使用者集區。使用者集區可使用下列格式：`arn:aws:cognito-idp:us-east-2:111122223333:userpool/${stageVariables.MyUserPool}`。

   1.  針對**權杖來源**，輸入 **Authorization** 作為標頭名稱，以在使用者成功登入時，傳遞 Amazon Cognito 傳回的身分或存取權杖。

   1. (選用) 在**權杖驗證**欄位中輸入規則表達式，以驗證身分權杖的 `aud` (對象) 欄位，再透過 Amazon Cognito 授權請求。請注意，當使用存取字符時，由於存取字符不包含該 `aud` 字段，所以此驗證拒絕該請求。

   1. 選擇**建立授權方**。

1. 建立 `COGNITO_USER_POOLS` 授權方之後，您可以提供從使用者集區佈建的身分字符來測試其調用情形。您無法使用存取字符來測試調用授權方。

   您可以呼叫 [Amazon Cognito 身分軟體開發套件](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-integrate-apps.html)來取得此身分字符，藉此執行使用者登入。您也可以使用 [https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)​ 動作。如果您未設定任何**授權範圍**，API Gateway 會將提供的權杖視為身分權杖。

上述程序會建立使用新建立之 Amazon Cognito 使用者集區的 `COGNITO_USER_POOLS` 授權方。視您在 API 方法中啟用授權方的方式而定，您可以使用從已整合使用者集區佈建的身分字符或存取字符。

**在方法中設定 `COGNITO_USER_POOLS` 授權方**

1. 選擇**資源**。選擇新方法或選擇現有方法。如有需要，請建立資源。

1. 在**方法請求**索引標籤的**方法請求設定**下，選擇**編輯**。

1. 針對**授權方**，從下拉式選單選取您剛才建立的 **Amazon Cognito 使用者集區授權方**。

1.  若要使用身分字符，請執行下列操作：

   1. 將**授權範圍**保留空白。

   1. 如有需要，在**整合請求**中，於內文對應範本中新增 `$context.authorizer.claims['property-name']` 或 `$context.authorizer.claims.property-name` 表達式，將指定的身分宣告屬性從使用者集區傳遞到後端。對於簡單的屬性名稱，例如 `sub` 或 `custom-sub`，兩個表示法完全相同。至於複雜的屬性名稱，例如 `custom:role`，則無法使用點表示法。例如，下列映射表達式會將宣告的[標準欄位](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) `sub` 和 `email` 傳送到後端：

      ```
      {
      	"context" : {
      		"sub" : "$context.authorizer.claims.sub",
      		"email" : "$context.authorizer.claims.email"
      	}
      }
      ```

      如已在設定使用者集區時宣告自訂的宣告欄位，您可以遵循相同的模式來存取自訂欄位。下列範例會取得自訂的宣告 `role` 欄位：

      ```
      {
      	"context" : {
      		"role" : "$context.authorizer.claims.role"
          }
      }
      ```

      如果自訂宣告欄位宣告為 `custom:role`，請使用下列範例來取得宣告的屬性：

      ```
      {
      	"context" : {
      		"role" : "$context.authorizer.claims['custom:role']"
          }
      }
      ```

1.  若要使用存取字符，請執行下列操作：

   1. 針對**授權範圍**，輸入在建立 Amazon Cognito 使用者集區時所設定之範圍的一或多個完整名稱。例如，在 [為 REST API 建立 Amazon Cognito 使用者集區](apigateway-create-cognito-user-pool.md) 提供的範例之後，其中一個範圍是 `https://my-petstore-api.example.com/cats.read`。

      在執行時間，如果在這個步驟中，方法內指定的任何範圍符合傳入字符宣告的範圍，則方法呼叫就會成功。否則，呼叫失敗並傳回 `401 Unauthorized` 回應。

   1.  選擇**儲存**。

1. 為您選擇的其他方法重複這些步驟。

使用 `COGNITO_USER_POOLS` 授權方，如果不指定 **OAuth Scopes (OAuth 範圍)** 選項，API Gateway 會將提供的字符視為身分字符，並使用使用者集區中的身分來驗證宣告的身分。否則，API Gateway 會將提供的字符視為存取字符，並根據方法中宣告的授權範圍來驗證字符中宣告的存取範圍。

除了使用 API Gateway 主控台之外，您也可以指定 OpenAPI 定義檔並將 API 定義匯入 API Gateway，在方法中啟用 Amazon Cognito 使用者集區。

**使用 OpenAPI 定義檔匯入 COGNITO\$1USER\$1POOLS 授權方**

1. 為您的 API 建立 (或匯出) OpenAPI 定義檔。

1. 指定 `COGNITO_USER_POOLS` 授權方 (`MyUserPool`) JSON 定義，做為 OpenAPI 3.0 的 `securitySchemes` 部分或 Open API 2.0 的 `securityDefinitions` 部分，如下所示：

------
#### [ OpenAPI 3.0 ]

   ```
     "securitySchemes": {
       "MyUserPool": {
         "type": "apiKey",
         "name": "Authorization",
         "in": "header",
         "x-amazon-apigateway-authtype": "cognito_user_pools",
         "x-amazon-apigateway-authorizer": {
           "type": "cognito_user_pools",
           "providerARNs": [
             "arn:aws:cognito-idp:{region}:{account_id}:userpool/{user_pool_id}"
           ]
         }
       }
   ```

------
#### [ OpenAPI 2.0 ]

   ```
     "securityDefinitions": {
       "MyUserPool": {
         "type": "apiKey",
         "name": "Authorization",
         "in": "header",
         "x-amazon-apigateway-authtype": "cognito_user_pools",
         "x-amazon-apigateway-authorizer": {
           "type": "cognito_user_pools",
           "providerARNs": [
             "arn:aws:cognito-idp:{region}:{account_id}:userpool/{user_pool_id}"
           ]
         }
       }
   ```

------

1. 若要使用身分字符授權方法，請將 `{ "MyUserPool": [] }` 新增到方法的 `security` 定義，如下列根資源中的 GET 方法所示。

   ```
     "paths": {
       "/": {
         "get": {
           "consumes": [
             "application/json"
           ],
           "produces": [
             "text/html"
           ],
           "responses": {
             "200": {
               "description": "200 response",
               "headers": {
                 "Content-Type": {
                   "type": "string"
                 }
               }
             }
           },
           "security": [
             {
               "MyUserPool": []
             }
           ],        
           "x-amazon-apigateway-integration": {
             "type": "mock",
             "responses": {
               "default": {
                 "statusCode": "200",
                 "responseParameters": {
                   "method.response.header.Content-Type": "'text/html'"
                 },
               }
             },
             "requestTemplates": {
               "application/json": "{\"statusCode\": 200}"
             },
             "passthroughBehavior": "when_no_match"
           }
         },
         ...
      }
   ```

1.  若要使用存取字符授權方法，請將上述安全性定義變更為 `{ "MyUserPool": [resource-server/scope, ...] }`：

   ```
     "paths": {
       "/": {
         "get": {
           "consumes": [
             "application/json"
           ],
           "produces": [
             "text/html"
           ],
           "responses": {
             "200": {
               "description": "200 response",
               "headers": {
                 "Content-Type": {
                   "type": "string"
                 }
               }
             }
           },
           "security": [
             {
               "MyUserPool": ["https://my-petstore-api.example.com/cats.read", "http://my.resource.com/file.read"]
             }
           ],        
           "x-amazon-apigateway-integration": {
             "type": "mock",
             "responses": {
               "default": {
                 "statusCode": "200",
                 "responseParameters": {
                   "method.response.header.Content-Type": "'text/html'"
                 },
               }
             },
             "requestTemplates": {
               "application/json": "{\"statusCode\": 200}"
             },
             "passthroughBehavior": "when_no_match"
           }
         },
         ...
      }
   ```

1. 如有需要，您可以使用適當的 OpenAPI 定義或延伸，設定其他的 API 組態設定。如需詳細資訊，請參閱[API Gateway 的 OpenAPI 擴充功能](api-gateway-swagger-extensions.md)。