目次
はじめに
AWS Cognito は、ユーザー認証やセッション管理を簡単に実装できる便利なサービスです。本記事では、Cognito のトークン管理や外部 ID プロバイダー(IdP)との連携方法、ユーザー情報の管理について詳しく解説します。
Cognitoで取得可能なトークン
Cognito では、ユーザーが認証されると以下の 3 種類のトークンを取得できます。
- ID トークン:ユーザーの属性情報を含む
- アクセストークン:API に対する認可情報を含む
- リフレッシュトークン:新しいトークンを取得するために使用
これらのトークンは、OAuth2.0 や OpenID Connect の標準的な仕様に基づいています。
トークンの用途
Cognitoに限った話ではありませんが、一般的にトークンは、認証と認可のために活用され、以下のような用途で使用されます。
- セッション管理
- Cognito のトークンは、ブラウザの
LocalStorage
やSessionStorage
に保存することができ、画面遷移などのリクエストの都度、リクエストヘッダに含めたトークンを検証することができます。 - これにより、リクエストしたユーザーの正当性を示し、ユーザーごとに適切な画面を表示することが可能になります。
- Cognito のトークンは、ブラウザの
- API リクエストの認可
- アクセストークンを使用して、API のアクセス権を管理できます。
- トークンからグループ情報を取得して、グループに応じたアプリケーション操作許可などの認可設定できます。
- ユーザ情報の画面表示
- ID トークンには、ユーザーの属性情報(名前やメールアドレスなど)が含まれています。そのため、アプリケーション内で現在ログインしているユーザー情報を表示することができます。
外部IdPとCognitoの統合
複数の外部 IdP(Google、Facebook、Apple など)を使用する場合、Cognito を間に挟むことで、トークンの取得と管理をCognitoに統一できます。これにより、トークンの検証がCognitoのみとなり、開発をシンプルにできます。
外部 IdP を利用する際には、以下の 2 つの方法があります。(裏を返せば、以下2つを使用しないと外部IdP連携はできないため注意が必要です。)
- Hosted UI
- マネージドログイン
実装例の参考:React アプリで Cognito を活用する
CognitoユーザープールとIDプールの違い
Cognito には ユーザープール と IDプール の 2 つの概念があります。ユーザープールは主に認証で利用し、IDプールは認可に使用します。なお、ユーザープールでは、グループの機能を使用することにより認可も可能です。
ユーザープール(User Pool)
- 認証を行い、トークンを発行する。
- グループ機能を利用して、IAM ロールのクレデンシャルを付与可能。これにより、アプリケーションのクライアント画面(ブラウザ)から直接 S3 や DynamoDB にアクセスできる。
IDプール(Identity Pool)
- ユーザープールや外部IdPに対して、IAM ロールのクレデンシャルを紐づけることができる。ユーザはクレデンシャルを取得して、権限に応じたS3アクセスなどの操作ができる。
ユーザー管理をシステム管理者でなく、アプリケーションの利用者に委任したい場合
「ユーザー側で管理者などの権限を自由に変更管理したい」という要件に対応する場合、Cognito の グループをユーザ側でメンテナンスする方法が考えられます。その場合は、以下のような実装方式が考えられます。(未検証)
- 前提として、管理者は管理者用のグループに所属しているものとする。
- グループの変更には Admin API の実行が必要なため、管理者のグループに対してCognitoを操作する権限を持った IAM ロールを割り当てておく。
- アプリケーションからグループに紐づくクレデンシャルを取得することでCognito操作権限を持たせて、Admin APIを実行する。
- メンテナンス可能なユーザーの参照範囲を制限するには、ユーザープールを分離する。
実装
Cognitoを使用した認証
- Amplifyのライブラリを利用することで、効率的に開発できる。
- ログインエンドポイント(マネージドログインやhosted uiの画面)の呼び出しおよび、認可エンドポイント(Cognito が提供するログインページを表示せずに直接外部 IdP のログインページに対してリダイレクトを行いたい場合に利用するエンドポイント)の呼び出しは、以下を利用する。
以下の例では、リダイレクト先にGoogleを指定しているため、認可エンドポイントとなる。
ログインエンドポイントでCognitoのログインページを表示したい場合は、IdPの引数を指定しないことで実現できる。以前は、federatedSignInが利用されていたが、2025/02時点では、以下が最新。
import { signInWithRedirect } from "aws-amplify/auth"
signInWithRedirect({ provider: "Google" })