はじめに
皆さん。こんにちは!
DreamHanksのエルムです。
今回はUserプール認証フローについて説明していきます。
前回の記事はパスワード & ユーザー管理です。
認証フロー (Authentication flows)
クライアント側の認証には、3つの異なるフローがあります。
- USER_SRP_AUTH:USER_SRP_AUTHフローは、SRPプロトコル(Secure Remote Password)を使用しており、パスワードはクライアントから離れることはなく、サーバーには知られていません。これは推奨されるフローで、デフォルトで使用されています。
- USER_PASSWORD_AUTH:USER_PASSWORD_AUTHフローは、ユーザー認証情報を暗号化せずにバックエンドに送信します。移行」トリガーを使用してユーザーをCognitoに移行し、ユーザーにパスワードのリセットを強制しないようにする場合、トリガーで起動されるLambda関数が提供された認証情報を検証する必要があるため、この認証タイプを使用する必要があります。
- CUSTOM_AUTH: CUSTOM_AUTHフローは、さまざまな要件に合わせてカスタマイズできる一連のチャレンジとレスポンスのサイクルを可能にするために使用されます。
異なるフローを使用するようにAuthを設定するには:
1 2 3 4 5 |
Auth.configure({ // その他の構成... // ... authenticationFlowType: 'USER_SRP_AUTH' | 'USER_PASSWORD_AUTH' | 'CUSTOM_AUTH', }) |
認証フローの詳細については、AWS Cognitoの開発者向けドキュメントをご覧ください。
USER_PASSWORD_AUTH フロー
USER_PASSWORD_AUTH認証フローのユースケースは、ユーザーをAmazon Cognitoに移行することです。
Authバックエンドの設定
認証フローUSER_PASSWORD_AUTHを使用するためには、Cognitoアプリのクライアントがそれを許可するように構成されている必要があります。AWSコンソールでは、「General settings」>「App clients」>「Show Details (for the affected client)」>「Enable username-password (non-SRP) フロー」のチェックボックスをオンにすることで行います。AWS CLIやCloudFormationを使用している場合は、「Explicit Auth Flows」のリストにUSER_PASSWORD_AUTHを追加してアプリクライアントを更新します。
Amazon Cognitoでユーザーを移行する方法 (Migrate users with Amazon Cognito)
Amazon Cognitoは、既存のユーザーディレクトリからCognitoにシームレスにユーザーを移行するトリガーを提供します。これを実現するには、ユーザープールの「移行」トリガーを設定します。このトリガーは、ユーザープールにまだ存在しないユーザーが認証したり、パスワードをリセットしたりするたびに、Lambda関数を呼び出します。
要するに、Lambda関数は、既存のユーザーディレクトリに対してユーザー資格を検証し、成功時にはユーザー属性とステータスを含むレスポンスオブジェクトを返します。エラーが発生した場合は、エラーメッセージが返されます。この移行フローの設定方法についてはこちらのドキュメントで、ラムダがリクエストオブジェクトとレスポンスオブジェクトをどのように扱うべきかについてはこちらのドキュメントで詳しく説明しています。
CUSTOM_AUTH フロー
Amazon Cognito User Pools は、ユーザーのアイデンティティを確認するために、パスワードに加えて、カスタムチャレンジタイプを有効にする認証フローのカスタマイズをサポートします。これらのチャレンジタイプには、CAPTCHAやダイナミックチャレンジ問題が含まれます。
カスタム認証フローの課題を定義するには、Amazon Cognitoの3つのLambdaトリガーを実装する必要があります。
カスタム認証チャレンジのためのLambda Triggersでの作業についての詳細は、Amazon Cognito Developer Documentationをご覧ください。
カスタム認証フロー (Custom authentication flow)
アプリでカスタム認証フローを開始するには、パスワードなしでsignInを呼び出します。カスタムチャレンジは、sendCustomChallengeAnswerメソッドを使って回答する必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import { Auth } from 'aws-amplify'; Auth.configure({ // その他の構成 // ... authenticationFlowType: 'CUSTOM_AUTH' }); let challengeResponse = "the answer for the challenge"; Auth.signIn(username, password) .then(user => { if (user.challengeName === 'CUSTOM_CHALLENGE') { // カスタムチャレンジの答えを送るために Auth.sendCustomChallengeAnswer(user, challengeResponse) .then(user => console.log(user)) .catch(err => console.log(err)); } else { console.log(user); } }) .catch(err => console.log(err)); |
CAPTCHA-basedによる認証 (CAPTCHA-based authentication)
ここでは、Lambda TriggerでCAPTCHAのチャレンジを作成するサンプルを紹介します。
Create Auth Challenge Lambda Triggerでは、ユーザーへの挑戦状としてCAPTCHAを作成します。CAPTCHA画像のURLと予想される答えが、プライベートチャレンジのパラメータに追加されます。
1 2 3 4 5 6 7 8 9 10 11 12 |
export const handler = async (event) => { if (!event.request.session || event.request.session.length === 0) { event.response.publicChallengeParameters = { captchaUrl: "url/123.jpg", }; event.response.privateChallengeParameters = { answer: "5", }; event.response.challengeMetadata = "CAPTCHA_CHALLENGE"; } return event; }; |
このDefine Auth Challenge Lambda Triggerは、カスタムチャレンジを定義します:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
export const handler = async (event) => { if (!event.request.session || event.request.session.length === 0) { // セッションがない場合や空の場合は、CUSTOM_CHALLENGEを送信します。 event.response.challengeName = "CUSTOM_CHALLENGE"; event.response.failAuthentication = false; event.response.issueTokens = false; } else if (event.request.session.length === 1 && event.request.session[0].challengeResult === true) { // CUSTOM_CHALLENGEに合格した場合、トークンを発行します。 event.response.failAuthentication = false; event.response.issueTokens = true; } else { // 何かが間違っている。認証失敗 event.response.failAuthentication = true; event.response.issueTokens = false; } return event; }; |
Verify Auth Challenge Response Lambda Triggerは、チャレンジ・アンサーを検証するために使用します:
1 2 3 4 5 6 7 8 9 |
export const handler = async (event, context) => { if (event.request.privateChallengeParameters.answer === event.request.challengeAnswer) { event.response.answerCorrect = true; } else { event.response.answerCorrect = false; } return event; }; |
終わりに
今回の記事は以上になります。
次回は[第10回] UIコンポーネントのカスタマイズを学びましょう。
ご覧いただきありがとうございます。
コメント