1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Cognito 既存のユーザープールから段階的に新規ユーザープールへ移行(マイグレーション)する

Last updated at Posted at 2025-06-05

🚀 Cognito User Migration Lambda 関数の実装ガイド

Amazon Cognito を使っていると、「既存のユーザーを新しいユーザープールにどうやって移行するのか?」という課題に直面することがあります。この記事では、初回ログイン時に旧ユーザープールから新ユーザープールへシームレスに移行する Lambda 関数の構築方法について、詳細に解説します。


🧠 背景と目的

  • Cognitoのユーザープールを再構成する必要がある
  • 既存ユーザーのパスワードを保持したまま移行したい
  • 移行のUXを損なわず、自動化したい

これを実現するのが、Cognito User Migration Trigger に対応する Lambda 関数です。


🛠 機能概要

この Lambda 関数では、次のような処理を行います。

  • ✅ 旧ユーザープールで認証を実行
  • 🔄 ユーザー属性(メールやカスタム属性など)を新ユーザープールに移行
  • 🔒 ユーザーを「確認済み(CONFIRMED)」として登録し、確認メールは送信しない

🌍 環境変数の設定

変数名 説明
OLD_USER_POOL_ID 移行元の旧ユーザープールID
OLD_CLIENT_ID 移行元ユーザープールのクライアントID

🔐 必要なIAMポリシー

Lambda にアタッチする IAM ポリシー例は以下の通りです:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "logs:CreateLogGroup",
      "Resource": "arn:aws:logs:{REGION}:{ACCOUNT_ID}:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": [
        "arn:aws:logs:{REGION}:{ACCOUNT_ID}:log-group:/aws/lambda/CognitoUserMigration:*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "cognito-idp:AdminInitiateAuth",
        "cognito-idp:AdminGetUser"
      ],
      "Resource": "arn:aws:cognito-idp:{REGION}:{ACCOUNT_ID}:userpool/{OLD_USER_POOL_ID}"
    }
  ]
}

{REGION}, {ACCOUNT_ID}, {OLD_USER_POOL_ID} は自身の環境に応じて置き換えてください。


⚙ トリガー設定

Cognito ユーザープールのトリガーで以下を設定:

  • UserMigration_Authentication:ユーザー認証時に発火
  • UserMigration_ForgotPassword:パスワードリセット時(※未サポート)

🔁 認証フローの流れ

  1. クライアントが USER_PASSWORD_AUTH でログインを試行
  2. 新ユーザープールにユーザーが存在しない
  3. UserMigration_Authentication トリガーで Lambda が起動
  4. Lambda で旧ユーザープールに対し認証実行
  5. 認証成功なら、新ユーザープールに属性を登録し CONFIRMED 状態に
  6. 認証失敗なら、そのまま失敗を返す

🧪 実装例(Python)

import boto3
import os

client = boto3.client("cognito-idp")

def lambda_handler(event, context):
    username = event["userName"]
    password = event["request"]["password"]

    try:
        auth_result = client.admin_initiate_auth(
            UserPoolId=os.environ["OLD_USER_POOL_ID"],
            ClientId=os.environ["OLD_CLIENT_ID"],
            AuthFlow="ADMIN_NO_SRP_AUTH",
            AuthParameters={
                "USERNAME": username,
                "PASSWORD": password
            }
        )

        # 認証成功 → 属性取得
        user = client.admin_get_user(
            UserPoolId=os.environ["OLD_USER_POOL_ID"],
            Username=username
        )

        attributes = {attr["Name"]: attr["Value"] for attr in user["UserAttributes"]}

        # 属性の移行(必要なものだけ抽出も可)
        event["response"]["userAttributes"] = {
            "email": attributes.get("email", ""),
            "email_verified": "true",
            # "custom:your_attr": attributes.get("custom:your_attr", "")
        }
        event["response"]["finalUserStatus"] = "CONFIRMED"
        event["response"]["messageAction"] = "SUPPRESS"
        event["response"]["forceAliasCreation"] = False

    except client.exceptions.NotAuthorizedException:
        raise Exception("認証失敗:パスワードが正しくありません")
    except client.exceptions.UserNotFoundException:
        raise Exception("認証失敗:旧ユーザープールにユーザーが存在しません")
    
    return event

🧬 移行される属性

  • 基本属性: email, email_verified
  • カスタム属性: custom: プレフィックスを持つすべての属性

✅ 使用方法まとめ

  1. Lambda に上記コードをデプロイ
  2. 環境変数を設定
  3. トリガーに UserMigration_Authentication を設定
  4. 新ユーザープールでユーザーがログインを試みると、旧ユーザープールから自動で移行される

🧪 AWS CLIでのテスト

AWS_PROFILE=your-profile aws cognito-idp initiate-auth \
  --auth-flow USER_PASSWORD_AUTH \
  --client-id {NEW_CLIENT_ID} \
  --auth-parameters USERNAME=user@example.com,PASSWORD=your-password

🧯 よくあるエラーと対処

エラー 原因
NotAuthorizedException 認証情報が誤っている
UserNotFoundException ユーザーが旧ユーザープールに存在しない
Lambdaエラー IAMポリシー不足、環境変数設定ミスなど

🔍 注意点・ベストプラクティス

  • パスワードリセットはサポートしていません(2025年6月現在)

  • messageAction: "SUPPRESS" を指定しないと確認メールが送信されます

  • event["response"]["finalUserStatus"] = "CONFIRMED" を忘れないこと

  • 移行処理は初回ログイン時のみ実行されます

  • ログイン画面は USER_PASSWORD_AUTH を使う必要があります

    重要:ログイン時に「ユーザーネーム+パスワード」をクライアント(フロントエンド)から Cognito に**直接渡す形式(USER_PASSWORD_AUTH)**でなければ、User Migration Lambda は発火しません。

    たとえば以下のような形式が該当します:

    aws cognito-idp initiate-auth \
      --auth-flow USER_PASSWORD_AUTH \
      --client-id YOUR_CLIENT_ID \
      --auth-parameters USERNAME=your_user,PASSWORD=your_pass
    

    一方、SRP(Secure Remote Password)フローや、ホスト型UI(Hosted UI)経由の認証では、UserMigration_Authentication はトリガーされません。


📌 まとめ

この Lambda 関数を活用することで、Cognito ユーザーを安全かつシームレスに移行できます。Cognitoの標準機能とAWS SDKの併用により、シンプルかつ堅牢な移行プロセスを実現可能です。


🔗 参考リンク

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?