AWS Cognito で認証機能を作る際の API Gateway・UserPool・UserPoolClient の関係性（メモ）

# API Gateway・UserPool・UserPoolClient の関係性


**1. Amazon Cognito User Pool（ユーザープール）**

* ユーザーディレクトリ：ユーザー名、パスワード、メールアドレスなどのユーザー情報を管理
* 認証機能：ユーザーのサインアップ、サインイン、パスワードリセットなどの認証機能を提供
* トークン発行：認証に成功したユーザーに対して、IDトークン、アクセストークン、リフレッシュトークンを発行

**2. Amazon Cognito User Pool Client（ユーザープールクライアント）**

* アプリケーションとユーザープールの仲介：アプリケーションがユーザープールとやり取りするためのインターフェースを提供
* クライアントID/シークレット：アプリケーションを識別するためのIDとシークレットを発行
* 認証フロー設定：アプリケーションで利用する認証フロー（例：Authorization Code Grant、Implicit Grant）を設定

**3. Amazon API Gateway**

* APIのエンドポイント：アプリケーションのAPIのエンドポイントを提供
* 認証/認可：Cognito User Poolで発行されたトークンを使って、APIへのアクセスを認証/認可
* リクエスト/レスポンス処理：APIへのリクエストを処理し、適切なバックエンドサービスに転送します。また、バックエンドサービスからのレスポンスを整形してアプリケーションに返す

**関係性**

1.  アプリケーションは、UserPoolClientを通してUserPoolにユーザーの認証をリクエストする
2.  UserPoolは、ユーザーの認証情報を検証し、認証に成功するとトークンを発行する
3.  アプリケーションは、API GatewayにAPIリクエストを送る際に、UserPoolから発行されたトークンを付与する
4.  API Gatewayは、受け取ったトークンを検証し、有効なトークンであればリクエストをバックエンドサービスに転送する
5.  バックエンドサービスは、API Gatewayからのリクエストを処理し、レスポンスをAPI Gatewayに返す
6.  API Gatewayは、レスポンスをアプリケーションに返す

**図解**

```
[アプリケーション] --- (1.認証リクエスト) ---> [UserPoolClient] --- (2.認証) ---> [UserPool]
                                                                        |
                                                                        (3.トークン発行)
                                                                        |
[アプリケーション] --- (3.トークン付与) ---> [API Gateway] --- (4.トークン検証/転送) ---> [バックエンドサービス]
                                         |                                         |
                                         <--- (6.レスポンス) --- (5.レスポンス) <---
```

**補足**

* API Gatewayは、Cognito User Poolだけでなく、他の認証/認可サービス（例：IAM、Lambda Authorizer）とも連携できる
* UserPoolClientは、複数のアプリケーションで共有できる
* UserPoolは、複数のUserPoolClientを持つことができる
* Amazon Cognito ユーザープールによる認証：[[https://docs.aws.amazon.com/ja](https://www.google.com/search?q=https://docs.aws.amazon.com/ja)\_jp/cognito/latest/developerguide/authentication.html](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/authentication.html)
* Amazon Cognito（ウェブ/モバイルアプリのユーザー管理） - AWS：[https://aws.amazon.com/jp/cognito/](https://aws.amazon.com/jp/cognito/)

# トークンの種類と有効期限

Cognito User Pool から発行されるトークンには、主に以下の3種類がある。

* **IDトークン:**
    * ユーザーの認証情報（ユーザーID、名前など）を含む
    * アプリケーションがユーザーの識別に使用
    * 有効期限は通常1時間程度
* **アクセストークン:**
    * APIへのアクセス権限を含む
    * API Gatewayがアクセス制御に使用
    * 有効期限は通常1時間程度
* **リフレッシュトークン:**
    * 新しいIDトークンとアクセストークンを取得するために使用
    * 有効期限はIDトークン、アクセストークンより長く設定できる

**トークンの使い回しと更新**

1.  **初期認証:**
    * アプリケーションは、UserPoolClientを通してUserPoolにユーザーの認証をリクエストし、3種類のトークンを取得する
2.  **APIリクエスト:**
    * アプリケーションは、アクセストークンをHTTPヘッダーに含めてAPI Gatewayにリクエストを送る
    * API Gatewayは、アクセストークンを検証し、有効なトークンであればリクエストをバックエンドサービスに転送する
3.  **トークンの有効期限切れ:**
    * アクセストークンの有効期限が切れると、API Gatewayはリクエストを拒否する
4.  **トークンの更新:**
    * アプリケーションは、リフレッシュトークンを使ってUserPoolに新しいIDトークンとアクセストークンをリクエストする
    * UserPoolは、リフレッシュトークンを検証し、有効なトークンであれば新しいトークンを発行する
5.  **APIリクエスト（再試行）:**
    * アプリケーションは、新しいアクセストークンを使ってAPI Gatewayにリクエストを再送する

**重要なポイント**

* アプリケーションは、トークンを安全に保管する必要があります
* リフレッシュトークンの有効期限も切れるため、定期的に再認証が必要になる場合があります
* Cognito User Poolの設定で、トークンの有効期限を調整できます


# API Gateway が Cognito User Poolと連携して、トークンの有効期限を検証する機能について

**API Gatewayの認証/認可機能**

* API Gatewayでは、Cognito User Poolで発行されたアクセストークンを使用して、APIリクエストの認証と認可を行う
* API Gatewayは、受け取ったアクセストークンを検証し、以下の項目をチェックする
    * トークンの署名が有効であること
    * トークンが有効期限内であること
    * トークンにAPIへのアクセス権限があること
* これらの検証に失敗した場合、API Gatewayは401 Unauthorizedエラーを返す

**トークンの検証方法**

* API Gatewayは、Cognito User Poolから公開鍵を取得し、アクセストークンの署名を検証する
* トークンには有効期限の情報が含まれており、API Gatewayは現在の時刻と比較して有効期限をチェックする

**API Gatewayの役割**

* API Gatewayは、トークンの有効期限をチェックすることで、不正なアクセスを防ぎ、APIのセキュリティを確保する
* アプリケーションは、API Gatewayにトークンの検証を任せることで、自身で検証処理を実装する必要がなくなる

**重要なポイント**

* API Gatewayは、Cognito User Poolと連携することで、トークンの有効期限を自動的に検証します
* アプリケーションは、トークンの有効期限を気にする必要はなく、API Gatewayに検証を任せることができます

# アプリケーションが UserPoolClient と通信する具体的な方法

**主な通信方法**

1.  **AWS SDKの使用:**
    * AWSが提供するSDK（Software Development Kit）を使用して、アプリケーションはUserPoolClientと通信する
    * SDKは、各プログラミング言語（JavaScript、Python、Javaなど）に対応したライブラリを提供し、認証に必要なAPIを簡単に呼び出すことができる
    * 例えば、JavaScriptの場合、`aws-sdk`または`aws-amplify`ライブラリを使用して、サインアップ、サインイン、トークン取得などの処理を行う
2.  **AWS Amplifyの使用:**
    * AWS Amplifyは、ウェブおよびモバイルアプリケーション向けのフレームワークであり、Cognito User Poolとの統合を容易にする
    * Amplifyは、認証に必要なUIコンポーネントやAPIを提供し、開発者は少ないコードで認証機能を実装できる
    * Amplifyは、SDKを内部的に使用しており、開発者はSDKの複雑な処理を意識する必要はない
3.  **直接API呼び出し:**
    * REST APIまたはGraphQL APIを使用して、アプリケーションはUserPoolClientと直接通信することも可能
    * ただし、この方法はSDKを使用する場合に比べて複雑であり、セキュリティ上の考慮事項も増える
    * 通常はSDKを使用する方法が推奨される

**通信の流れ（例：JavaScript SDK）**

1.  **SDKの初期化:**
    * アプリケーションは、UserPoolClientのクライアントIDなどの設定情報を使用して、SDKを初期化する
2.  **認証リクエスト:**
    * ユーザーがサインインなどの操作を行うと、アプリケーションはSDKのAPIを呼び出してUserPoolClientに認証リクエストを送信する
    * リクエストには、ユーザー名、パスワードなどの認証情報が含まれる
3.  **UserPoolClientの処理:**
    * UserPoolClientは、受け取ったリクエストをUserPoolに転送し、ユーザーの認証を行う
4.  **トークン発行:**
    * 認証に成功すると、UserPoolはIDトークン、アクセストークン、リフレッシュトークンを発行し、UserPoolClient経由でアプリケーションに返す
5.  **トークンの保存:**
    * アプリケーションは、受け取ったトークンを安全な場所に保存する
6.  **APIリクエスト:**
    * アプリケーションは、アクセストークンをHTTPヘッダーに含めてAPI Gatewayにリクエストを送信する

**重要なポイント**

* SDKを使用することで、認証処理を簡略化し、セキュリティを向上させることができます
* Amplifyを使用すると、さらに開発効率を高めることができます
* 直接API呼び出しは、高度なカスタマイズが必要な場合にのみ検討してください