
はじめに
こんにちは。開発 2 部でリテールハブの小売アプリを担当している池です。 2024 年 11 月、AWS Cognito の認証機能にパスワードレス認証機能(Email/SMS OTP やパスキー)が標準機能として追加されました。
これまでは Cognito でパスワードレス認証を実現するにはカスタム Lambda トリガー(CUSTOM_AUTH 認証フロー)を利用して OTP 認証を実装する必要がありましたが、標準機能として追加されたことによって Lambda を使わずに Cognito のみで OTP を実現することができるようになりました。
小売アプリの開発においてパスワードレス認証を検討する機会があったため本記事では Cognito パスワードレス認証を試して、設定方法や認証フローおよび必要な API を確認します。
Cognito パスワードレス認証の 3 つの方式
Cognito の標準パスワードレス認証には以下の 3 つの方式があります。
- Email OTP - メールで送信されるワンタイムパスワードで認証
- SMS OTP - SMS で送信されるワンタイムパスワードで認証
- WebAuthn/パスキー - 生体認証やハードウェアトークンで認証
今回は、この中から Email OTP 認証 を AWS CLI から試し、サインアップからトークン取得までの一連の流れを確認してみます。
事前準備
AWS コンソールでの設定(パスワードレス認証のアクティベート設定)
1. User Pool の作成・設定
Cognito User Pool を作成した後、コンソールで以下を設定します。
サインイン設定
- 「認証 > サインイン > 選択ベースのサインインのオプション」から編集に遷移
- 「使用できる選択肢」で「メールメッセージのワンタイムパスワード」を選択して保存

この設定をすることにより「パスワードなしのステータス」がアクティブになります。

パスワードレス認証(USER_AUTH 認証フロー)の有効化
USER_AUTH は 2024 年 11 月に追加された Cognito のパスワードレス認証フローです。従来の CUSTOM_AUTH のようなカスタム Lambda が不要で、標準機能として Email/SMS OTP やパスキー認証に対応しています。認証フローの USER_AUTH を有効にする設定を行います。
- 「アプリケーションクライアント > アプリケーションクライアントに関する情報」から編集に遷移
- 「認証フロー」の「選択ベースのサインイン: ALLOW_USER_AUTH」にチェックをつけて保存
- オプション:OTP の有効期限をカスタマイズ(デフォルト 3 分)

このフローを有効化することで、サインアップから認証まで一貫してパスワードレスで実装できます。
必要な情報の確認
設定完了後、以下の情報を控えておきます。
- User Pool ID - 例:
ap-northeast-1_XXXXXXXXX - App Client ID - 例:
1a2b3c4d5e6f7g8h9i0j
フロー概要
今回は Email OTP 認証における以下の 2 つのフローを確認したいと思います。
A. サインアップ後の自動サインインフロー(初回登録時)
- サインアップ(ユーザー登録) → OTP 送信
- OTP 入力 → Session 返却
- Session を使って自動サインイン → トークン取得
B. 通常のサインインフロー(2 回目以降)
- サインイン開始(OTP 発行要求)→ OTP 送信
- OTP 入力 → トークン取得
シーケンス図
A. サインアップ後の自動サインインフロー
初回登録時は、サインアップと同時に OTP が送信され、ユーザーが認証コードを入力すると Session が返却されます。この Session を使うことで、追加の認証処理を挟まずにトークンを取得し、自動的にサインインまで完了できます。つまり「ユーザー登録 → メール確認 → そのままサインイン」が一気通貫で実現される流れです。

B. 通常のサインインフロー(2 回目以降)
2 回目以降のサインインでは、まず initiate-auth を実行すると OTP がメールで送信されると同時に Session が返却されます。ユーザーは受け取った OTP を入力し、その Session と組み合わせて respond-to-auth-challenge を呼び出すことで認証が完了し、トークンが返却されます。 まとめると、通常サインインは「OTP 発行(Session 付与)→ OTP 入力 & Session 提示 → トークン取得」という流れになります。

API/CLI コマンドまとめ
Email OTP 認証で使用する API/CLI コマンドの一覧
| フェーズ | API/CLI コマンド | 用途 | レスポンス |
|---|---|---|---|
| A. サインアップ後の自動サインインフロー | |||
| サインアップ | sign-up |
ユーザー登録 | UserSub、認証コード送信先 |
| 認証コード確認 | confirm-sign-up |
メールアドレス確認 | Session(自動サインイン用) |
| 自動サインイン | initiate-auth (SESSION) |
Session でサインイン | IdToken、AccessToken、RefreshToken |
| B. 通常のサインインフロー | |||
| サインイン開始 | initiate-auth (USER_AUTH) |
OTP 送信 | Session、EMAIL_OTP チャレンジ |
| 認証コード確認 | respond-to-auth-challenge |
OTP 入力・トークン取得 | IdToken、AccessToken、RefreshToken |
| 共通操作 | |||
| OTP 再送 (サインアップ時) | resend-confirmation-code |
新しい OTP 送信 | 送信先情報 |
| OTP 再送 (サインイン時) | initiate-auth (USER_AUTH) |
新しい OTP 送信 | 新しい Session |
CLI で実行してみる
(1) サインアップ
事前準備のパスワードレス認証の設定を行っておくことで、パスワード不要で sign-up を実行することができます。
aws cognito-idp sign-up --client-id <APP_CLIENT_ID> --username <email@example.com> --user-attributes Name=email,Value=<email@example.com>
パラメータ解説
--client-id: User Pool に紐づくアプリクライアントの ID--username: サインイン時に使用するユーザー名(ここではメールアドレスを指定)--user-attributes: ユーザー属性。Email OTP を使う場合は Name=email を必須で登録
レスポンス例
{ "UserConfirmed": false, "CodeDeliveryDetails": { "Destination": "y***@e***", "DeliveryMedium": "EMAIL", "AttributeName": "email" }, "UserSub": "d7f40a38...", "Session": "AYABeLIBKr5g..." }
CLI の実行に成功すると認証コードが書かれた Email が届きます。

(2) 認証コードの確認(サインアップ時)
認証コードの確認はconfirm-sign-upで行います。
aws cognito-idp confirm-sign-up --client-id <APP_CLIENT_ID> --username <email@example.com> --confirmation-code 123456
レスポンス例
{ "Session": "AYABeLIBKr5g..." }
パスワードレス認証が有効な場合、confirm-sign-up のレスポンスに Session が含まれます。この Session を使用して次のステップでサインアップ時のシームレスな自動サインインが可能になります。
(2-補足) 認証コード再送
認証コードを再送する際にはresend-confirmation-codeを利用します。
aws cognito-idp resend-confirmation-code --client-id <APP_CLIENT_ID> --username <email@example.com>
レスポンス例
{ "CodeDeliveryDetails": { "Destination": "y***@e***", "DeliveryMedium": "EMAIL", "AttributeName": "email" } }
(3) サインアップ後の自動サインイン
confirm-sign-up で Session が返された場合、その Session を使用してinitiate-authを行うことで自動サインインが可能です。
aws cognito-idp initiate-auth --auth-flow USER_AUTH --client-id <APP_CLIENT_ID> --auth-parameters USERNAME=<email@example.com>,SESSION=<confirm-sign-up-session>
パラメータ解説
--auth-flow: パスワードレス認証フローであるUSER_AUTHを指定--auth-parameters: USERNAME にメールアドレスを指定。ここではパスワード不要。SESSION にconfirm-sign-upのレスポンスで返ってきた Session をそのまま利用。
成功時レスポンス
{ "ChallengeParameters": {}, "AuthenticationResult": { "AccessToken": "eyJraWQiO...", "ExpiresIn": 3600, "TokenType": "Bearer", "RefreshToken": "eyJjdHkiO...", "IdToken": "eyJraWQiO..." } }
(4) 通常の OTP 認証開始(2 回目以降のサインイン)
2 回目以降のサインインでは、USER_AUTH フローを使用して OTP 認証を開始します。
aws cognito-idp initiate-auth --auth-flow USER_AUTH --client-id <APP_CLIENT_ID> --auth-parameters USERNAME=<email@example.com>
パラメータ解説
--auth-flow: パスワードレス認証フローであるUSER_AUTHを指定--auth-parameters: USERNAME にメールアドレスを指定。ここではパスワード不要
レスポンス例
{ "ChallengeName": "EMAIL_OTP", "Session": "AYABeLnHu7...", "ChallengeParameters": { "CODE_DELIVERY_DELIVERY_MEDIUM": "EMAIL", "CODE_DELIVERY_DESTINATION": "y***@e***" }, "AvailableChallenges": ["EMAIL_OTP"] }
(5) 認証コードの確認(サインイン時)
認証コードの確認はrespond-to-auth-challengeを利用します。
aws cognito-idp respond-to-auth-challenge --client-id <APP_CLIENT_ID> --challenge-name EMAIL_OTP --session "AYABe9eY..." --challenge-responses USERNAME=<email@example.com>,EMAIL_OTP_CODE=123456
パラメータ解説
--challenge-name: 今回はEMAIL_OTPを指定--session:initiate-authのレスポンスで返ってきた Session をそのまま利用--challenge-responses: ユーザー名と OTP をセットで渡す
レスポンス例
{ "ChallengeParameters": {}, "AuthenticationResult": { "AccessToken": "eyJraWQiOi...", "ExpiresIn": 3600, "TokenType": "Bearer", "RefreshToken": "eyJjdHkiOi...", "IdToken": "eyJraWQiOi..." } }
(5-補足) OTP の再送
OTP が届かない/期限切れの場合は、再度 initiate-auth を実行すると新しい OTP がメールに送信されます。
制限事項
MFA との併用制限
パスワードレス認証には以下の MFA 関連の制限があります。
- ユーザーは MFA またはパスワードレス認証のいずれか一方のみ使用可能(両方の併用は不可)
- MFA を「必須」に設定している場合
- パスワードレス認証を設定できない
- MFA を「オプション」に設定している場合
- MFA を設定済みのユーザー:パスワードレス認証を使用できない
- MFA 未設定のユーザー:パスワードレス認証を使用できる
- MFA を「必須」に設定している場合
つまり、パスワードレス認証を利用する場合は MFA を「オプション」または「なし」に設定する必要があります。この制限は AWS Cognito の仕様によるもので、詳細は 公式ドキュメント を参照してください。
機能プラン
2025 年 9 月時点で Cognito には Lite, Essential, Pro という 3 つのプランがあります。 それぞれのプランにおいて利用できる機能と料金体系が異なり、Lite < Essential < Pro の順番で機能が豊富になり、その分料金は高くなります。
Cognito パスワードレス認証を利用するには Essential 以上のプランが必要になります。
※ 機能プランおよび料金体系は変更されるのでご注意ください。
まとめ
本記事では 2024 年 11 月から Cognito 標準機能として利用可能になったパスワードレス認証(Email OTP)で AWS CLI を使ってサインアップからサインインまでのフローを確認しました。 これにより、従来はカスタム Lambda が必須だった OTP 認証を、Cognito 標準機能のみでシンプルに実現できることが分かりました。
実運用では MFA との併用制限 や プラン要件 に注意する必要がありますが、ユーザー体験を向上させたいケース等で有効な選択肢となります。 今回は Email OTP のみを確認しましたが、パスキー(WebAuthn)といった他の方式も検証してみたいと思います。
最後まで読んでいただきありがとうございました。少しでも参考になれば幸いです。