LoginSignup
24
19

More than 5 years have passed since last update.

Confirmed状態のCognitoユーザーをBoto 3で即作成する

Posted at

概要

指定されたユーザー情報を使って、すぐにログインできるConfirmed状態のCognitoユーザーをバックエンド側でサクッと作成したい。
admin_create_userだとForce Change Password状態となるので、この後に処理が必要。

今のところの結論

import boto3

username = '{ユーザー名}'
password = '{パスワード}'
email = '{メールアドレス}'

user_pool_id = '{ユーザープールID}'
client_id = '{アプリクライアントID}'

cognito_idp = boto3.client('cognito-idp')

# ユーザーを作成する。
cognito_idp.admin_create_user(
    UserPoolId=user_pool_id,
    Username=username,
    TemporaryPassword=password,
    UserAttributes=[{'Name': 'email', 'Value': email}],
    MessageAction='SUPPRESS'
)

# ログインを試みる。(パスワードの変更を要求される。)
response = cognito_idp.admin_initiate_auth(
    UserPoolId=user_pool_id,
    ClientId=client_id,
    AuthFlow='ADMIN_NO_SRP_AUTH',
    AuthParameters={'USERNAME': username, 'PASSWORD': password},
)
session = response['Session']

# パスワードを変更する。
response = cognito_idp.admin_respond_to_auth_challenge(
    UserPoolId=user_pool_id,
    ClientId=client_id,
    ChallengeName='NEW_PASSWORD_REQUIRED',
    ChallengeResponses={'USERNAME': username, 'NEW_PASSWORD': password},
    Session=session
)

解説

以下の3ステップでConfirmed状態のユーザーを作成しています。

  1. ユーザーの作成(admin_create_user
  2. 最初の認証(admin_initiate_auth
  3. パスワードの変更(admin_respond_to_auth_challenge

1. ユーザーの作成(admin_create_user

管理者によるユーザーの作成を行う。
通常は作成した時に仮パスワードが通知されますが、MessageAction='SUPPRESS'で無効にできます。

2. 最初の認証(admin_initiate_auth

管理者による最初の認証を試みる。
すると、以下のようなレスポンスが返却され、新しいパスワードが必要だということが分かります。この中のSessionが次の処理で必要となります。

{'ChallengeName': 'NEW_PASSWORD_REQUIRED',
 'ChallengeParameters': (省略),
 'ResponseMetadata': (省略),
 'Session': '{セッションを表す長い文字列}'}

また、AuthFlow='ADMIN_NO_SRP_AUTH'とする場合は、アプリクライアントの設定で「サーバーベースの認証でサインイン API を有効にする (ADMIN_NO_SRP_AUTH)」を有効にしておく必要があります。SRPというのは認証のプロトコルで、使用するとセキュアでない通信経路でもユーザー名とパスワードによる認証を安全に行なえるようになるようですが、実装が難しくなり、また今回は全てバックエンドでの処理となるので、使用しなくても良いこととしています。

3. パスワードの変更(admin_respond_to_auth_challenge

管理者によるNEW_PASSWORD_REQUIREDに対する返答。
成功すると各種トークンが返却され、ユーザーの状態もConfirmedへ移行します。これでめでたくユーザーが普通にログインできるようになりました!

なお、コードにある通り、新しいパスワードは仮のパスワードと同じでも問題ありませんでした。

他の方法

一応、次の方法でもConfirmed状態のユーザーを作成することができます。

# ユーザーがサインアップする。
cognito_idp.sign_up(
    ClientId=client_id,
    Username=username,
    Password=password,
    UserAttributes=[{'Name': 'email',' Value': email}]
)

# それを管理者が承認する。
cognito_idp.admin_confirm_sign_up(
    UserPoolId=user_pool_id,
    Username=username
)

簡単だったので、最初はこちらの方法を使っていたのですが、アプリクライアントの設定で「アプリベースの認証でユーザー名とパスワードの (SRP を使用しない) フローを有効にする (USER_PASSWORD_AUTH)」を無効にしたり、属性の書き込み権限を変更したりするとsign_upができなくなるので、全て管理者の操作で行える上記の方法に変更しました。

24
19
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
24
19