AWS Cognitoを使ってみた

Cognitoとは
ユーザー認証とユーザーデータ管理をしてくれるAWSのサービス。モバイルアプリやWebアプリの認証機能を簡単に実装でき、ユーザーデータの安全な管理を実現できる。
1. ユーザープール (User Pool)
ユーザープールは、ユーザー登録、認証、アカウントの復元機能などを提供するディレクトリ。
ユーザーはこのプールに登録され、認証時にこのプール内のデータをもとに認証が行われる。
出典『Amazon Cognitoとは?』から抜粋
機能例
- 認証:ユーザーの新規登録、ログイン、ログアウト、パスワードリセット、etc...
- 多要素認証 (MFA): SMSやアプリを用いた多要素認証を簡単に設定できます。
- ソーシャルログイン: Google, Facebook, OIDC IDプロバイダー経由のサインイン
- ユーザー属性管理: 名前やメールアドレスなどの属性情報を保存・管理できます。
2. IDプール (Identity Pool)
IDプールは、ユーザーがAWSリソースにアクセスするための一時的な認証情報(トークン)を提供する。ユーザーは、SNSアカウントやユーザープールで認証を行い、その結果得られたトークンを使って、S3やDynamoDBなどのAWSリソースにアクセスできる。
出典『Amazon Cognitoとは?』から抜粋
ユーザープールはユーザーの認証と管理を行い、IDプールはAWSリソースへの認可を行う。
ユーザープールで認証、IDプールで認可を行う
-
ユーザー認証: ユーザーがCognitoユーザープールを通じて認証されると、IDトークンが発行される。
-
IDプールでのトークン交換: 認証されたIDトークンをIDプールに渡すと、IDプールはそのユーザーに対応する一時的なAWS認証情報(AWSアクセスキー、シークレットキー、セッショントークン)を発行する。
-
AWSリソースへのアクセス: 発行された一時的な認証情報を使って、S3バケットやDynamoDBなどのAWSリソースにアクセスする。このアクセスは、IDプールに設定されたIAMロールとポリシーによって制御される。

LINEソーシャルログインを連携する
ユーザープールでのサインインオプションとしてOIDCプロバイダー経由のサインイン方法があり、LINEのログインチャネルを使用してLINEでログイン認証したユーザーをCognitoのユーザープールで管理することができる。
大まかな流れ
-
ユーザーが外部プロバイダーでログイン
- ユーザーがアプリケーションで外部プロバイダー(LINE)を使用してログインします。
-
外部プロバイダーが認証トークンを発行
- 外部プロバイダーが認証に成功すると、認証トークン(IDトークン、アクセストークンなど)が発行されます。
-
アプリケーションが認証トークンをCognitoに渡す
- アプリケーションは外部プロバイダーから受け取ったトークンをAmazon Cognitoに渡し、ユーザーの認証をリクエストします。
-
Cognitoがトークンを検証
- Cognitoは外部プロバイダーの公開鍵を使用してトークンの署名を検証し、有効なトークンであることを確認します。
-
Cognitoがユーザープールにユーザーを作成または更新
- トークンが有効である場合、Cognitoはトークン内のクレーム(ユーザー情報)を使用して、ユーザープール内にユーザーを作成または更新します。新しいユーザーが既存のユーザーと同一であるかどうかを判断するために、通常はトークン内の一意の識別子(
sub
クレームやemail
クレームなど)を使用します。
- トークンが有効である場合、Cognitoはトークン内のクレーム(ユーザー情報)を使用して、ユーザープール内にユーザーを作成または更新します。新しいユーザーが既存のユーザーと同一であるかどうかを判断するために、通常はトークン内の一意の識別子(
LINEログインの場合、LINEのIDトークンに含まれるsub
クレームがCognitoユーザープール内のユーザーのsub
属性に対応する。
このsub
フィールドがCognitoユーザープール内のsub
属性と比較され、一致するユーザーが存在するかどうかが判断される。
{
"iss": "https://access.line.me",
"sub": "U1234567890abcdef1234567890abcdef",
"aud": "1234567890",
"exp": 1504169092,
"iat": 1504263657,
"nonce": "0987654asdf",
"amr": ["pwd"],
"name": "Taro Line",
"picture": "https://sample_line.me/aBcdefg123456"
}
LINEソーシャルログインの設定方法
こちらの記事を参照してユーザープールにLINEソーシャルログインの設定を加えました。
参考

属性マッピング
作成したユーザープールのどの属性にLINEから得た情報をマッピングするかを指定する。
LINEプラットフォームは、OpenID Connect (opens new window)仕様に準拠するIDトークンを発行しているため、LINEプラットフォームからユーザーのプロフィール情報(ユーザーID・表示名・プロフィール画像・メールアドレス)を安全に取得できます。
LINEのIDトークンに含まれるプロパティ名をユーザープールの属性に指定することで情報がマッピングされる。
ユーザー名
: line_<line UID>
ユーザーID(sub)
: Cognito発行のUID
メールアドレス
: LINEに登録しているメールアドレス※
※LINEソーシャルログインでアカウントを作成した場合、Cognitoのメールアドレス属性に渡されるLINEのメールアドレスは「未検証」の状態で渡される。そのため、Cognito上で検証済みのメールアドレスを抽出したい場合は、メールアドレスの属性確認を別フローで行う必要がある。
※またLINEログインの場合一度メールアドレス属性を「確認済」としても、ログインする度に属性が「未検証」状態へと上書きマッピングされてしまうため、検証済みのメールアドレスを属性として保持したい場合は工夫が必要。(カスタム認証フローや、カスタム属性を使う方法も考えられる)

ユーザーアカウントの確認
アカウント作成前、メールアドレス・パスワード変更時に本人確認をする場合のフロー。
出典: 『ユーザーアカウントのサインアップと確認』から抜粋
メールアドレスを使用した検証フローの場合、以下2種類の検証方法がある。
(ユーザープール>>メッセージング>>メッセージテンプレートで編集可能)
-
確認コード
- 確認コードをメールで受け取り、UI上のフォームにコードを入力する方法
-
リンク
-
確認コードが埋め込まれたリンクをメールで受け取り、リンクを踏むことで検証完了となる
-
デフォルトではリンクの遷移先はCognitoが用意したUI(HostedUI)に飛ぶため、自作のクライアントアプリに遷移したい場合は、Eメールプロバイダーを「AmazonSES」にして、メッセージテンプレートを自作する必要がある。
-
https://dev.classmethod.jp/articles/cognito-user-pool-signup-customize/
-
- メッセージのカスタマイズ