

# REST API と Amazon Cognito ユーザープールを統合する
<a name="apigateway-enable-cognito-user-pool"></a>

API Gateway で Amazon Cognito ユーザープールを作成し、そのユーザープールを使用する `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` オーソライザーを作成できます。1 つの `COGNITO_USER_POOLS` オーソライザーには最大 1,000 のユーザープールを使用できます。この制限を増やすことはできません。

**重要**  
以下の手順の実行後、API をデプロイまたは再デプロイして変更を伝達する必要があります。API のデプロイの詳細については、「[API Gateway で REST API をデプロイする](how-to-deploy-api.md)」を参照してください。

**API Gateway コンソールを使用して `COGNITO_USER_POOLS` 認証を作成するには**

1. 新しい API を作成、または API Gateway に既存の API を選択します。

1. メインナビゲーションペインで、**[オーソライザー]** を選択します。

1. **[オーソライザーの作成]** を選択します。

1. ユーザープールを使用するように新しいオーソライザーを設定するには、次の手順を実行します。

   1.  **[オーソライザー名]** に名前を入力します。

   1. **[オーソライザータイプ]** には、**[Cognito]** を選択します。

   1. **[Cognito ユーザープール]** では、Amazon Cognito を作成した場所 AWS リージョン を選択し、使用可能なユーザープールを選択します。

      ユーザープールを定義するには、ステージ変数を使用できます。ユーザープールには、形式として `arn:aws:cognito-idp:us-east-2:111122223333:userpool/${stageVariables.MyUserPool}` を使用します。

   1.  ユーザーがサインインした際に Amazon Cognito が返す ID またはアクセストークンを渡すように、**[トークンソース]** には、ヘッダー名として **Authorization** と入力します。

   1. (オプション) 必要に応じて **[トークン検証]** フィールドに正規表現を入力して、リクエストが Amazon Cognito で承認される前に ID トークンの `aud` (対象者) フィールドを検証します。アクセストークンを使用する場合、この検証では、アクセストークンが `aud` フィールドを含まないために要求が拒否されることに注意してください。

   1. **[オーソライザーの作成]** を選択します。

1. `COGNITO_USER_POOLS` オーソライザーを作成した後、ユーザープールからプロビジョニングされた ID トークンを指定して、呼び出しをテストできます。アクセストークンを使用してオーソライザーの呼び出しをテストすることはできません。

   [Amazon Cognito ID SDK](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-integrate-apps.html) を呼び出してユーザーサインインを実行することで、この ID トークンを取得できます。[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 は指定されたトークンを ID トークンとして扱います。

前述の手順では、新しく作成した Amazon Cognito ユーザープールを使用する `COGNITO_USER_POOLS` オーソライザーを作成します。API メソッドでオーソライザーを有効にした方法に応じて、統合トークンまたは統合ユーザープールからプロビジョニングされたアクセストークンを使用できます。

**メソッドで `COGNITO_USER_POOLS` オーソライザーを設定するには**

1. **[リソース]** をクリックします。新しいメソッドを選択するか、既存のメソッドを選択します。必要に応じて、リソースを作成します。

1. **[メソッドリクエスト]** タブの **[メソッドリクエスト設定]** で、**[編集]** を選択します。

1. **[オーソライザー]** には、ドロップダウンメニューから、先ほど作成した **Amazon Cognito ユーザープールオーソライザー**を選択します。

1.  ID トークンを使用するには、次の操作を行います。

   1. **[認可スコープ]** は、空のままにします。

   1. 必要に応じて、**[統合リクエスト]** で、ユーザープールからバックエンドに特定の ID クレームプロパティを渡すために、本文マッピングテンプレートに `$context.authorizer.claims['property-name']` 式または `$context.authorizer.claims.property-name` 式を追加します。`sub` や`custom-sub` などの簡単なプロパティ名については、2 つの表記法は同じです。`custom:role` などの複雑なプロパティ名の場合、ドット表記は使用できません。たとえば、以下のマッピング式は、バックエンドに、クレームの `sub` および `email` の[標準フィールド](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)を渡します。

      ```
      {
      	"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 ユーザープールが作成された際に設定されたスコープのフルネームを 1 つ以上入力します。たとえば、「[REST API 用の Amazon Cognito ユーザープールを作成する](apigateway-create-cognito-user-pool.md)」の例では、スコープの 1 つは `https://my-petstore-api.example.com/cats.read` です。

      実行時に、このステップのメソッドで指定されたスコープが、受信トークンで要求されているスコープと一致する場合、メソッド呼び出しは成功します。それ以外の場合、`401 Unauthorized` レスポンスでコールが失敗します。

   1.  **[保存]** を選択します。

1. 選択した他のメソッドにこれらの手順を繰り返してください。

`COGNITO_USER_POOLS` オーソライザーで、[**OAuth Scopes**] オプションが指定されていない場合、API Gateway は、指定されたトークンを ID トークンとして処理し、ユーザープールからのトークンに対して、要求された ID を検証します。それ以外の場合、API Gateway は提供されたトークンをアクセストークンとして処理し、トークンで要求されたアクセススコープをメソッドで宣言されている承認スコープと照合して検証します。

API Gateway コンソールを使う代わりに、OpenAPI 定義ファイル内で指定してメソッド上での Amazon Cognito ユーザープールを有効化し、API 定義を API Gateway にインポートすることもできます。

**OpenAPI 定義ファイルを使って COGNITO\$1USER\$1POOLS オーソライザーをインポートするには**

1. API 用の OpenAPI 定義ファイルを作成 (またはエクスポート) します。

1. OpenAPI 3.0 の `COGNITO_USER_POOLS` セクション、または Open API 2.0 の `MyUserPool` セクションの一部として、`securitySchemes` オーソライザー (`securityDefinitions`) JSON を次のように指定します。

------
#### [ 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. メソッドの認可にアイデンティティトークンを使用するには、ルートリソースの次の GET メソッドに示すように、メソッドの `{ "MyUserPool": [] }` 定義に `security` を追加します。

   ```
     "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)」を参照してください。