every Tech Blog

株式会社エブリーのTech Blogです。

Cognito 標準機能のパスワードレス認証(Email OTP)を AWS CLI で試してみる

はじめに

こんにちは。開発 2 部でリテールハブの小売アプリを担当している池です。 2024 年 11 月、AWS Cognito の認証機能にパスワードレス認証機能(Email/SMS OTP やパスキー)が標準機能として追加されました。

これまでは Cognito でパスワードレス認証を実現するにはカスタム Lambda トリガー(CUSTOM_AUTH 認証フロー)を利用して OTP 認証を実装する必要がありましたが、標準機能として追加されたことによって Lambda を使わずに Cognito のみで OTP を実現することができるようになりました。

小売アプリの開発においてパスワードレス認証を検討する機会があったため本記事では Cognito パスワードレス認証を試して、設定方法や認証フローおよび必要な API を確認します。

Cognito パスワードレス認証の 3 つの方式

Cognito の標準パスワードレス認証には以下の 3 つの方式があります。

  1. Email OTP - メールで送信されるワンタイムパスワードで認証
  2. SMS OTP - SMS で送信されるワンタイムパスワードで認証
  3. 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. サインアップ後の自動サインインフロー(初回登録時)

  1. サインアップ(ユーザー登録) → OTP 送信
  2. OTP 入力 → Session 返却
  3. Session を使って自動サインイン → トークン取得

B. 通常のサインインフロー(2 回目以降)

  1. サインイン開始(OTP 発行要求)→ OTP 送信
  2. 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 を「オプション」または「なし」に設定する必要があります。この制限は 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)といった他の方式も検証してみたいと思います。

最後まで読んでいただきありがとうございました。少しでも参考になれば幸いです。

参考リンク