🦁

Amazon Cognitoを使ったユーザの仮登録→本登録の流れ

2022/04/12に公開

Cognitoを使ったユーザ登録(仮登録→本登録)について、調査・試した結果をまとめていきます。

Cognitoのユーザ登録には大きく2つのパターンがある

Cognitoには、管理者として他のユーザを登録するパターンユーザが自分自身で登録するパターンの2つがあります(私が勝手にパターン分けしただけで、公式の見解ではないです)。
それぞれのパターンの具体的な流れについては、以降の章に記載しますが、先に、まとめの表を記載しておきます。

パターン 仮登録時のパスワード要否 仮登録時に使用する関数 仮登録時に送られる情報 使用するケース
管理者として他のユーザを登録するパターン 不要 aws-sdkのadminCreateUser関数(バックエンド) 仮パスワード ユーザの登録を管理者でコントロールしたい業務アプリ
ユーザが自分自身で登録するパターン 必要 amplifyのsignUp関数(フロントエンド)
(aws-sdkのsignUp関数でも可能)
検証コード ユーザが自身で登録可能なコンシューマ向けアプリ

今回記載した2つのパターンを分けるポイントになったのは、2列目に記載している、仮登録時のパスワードの要否です。
ユーザが自分自身で登録するパターンに記載している、signUp関数を使っても、管理者によるユーザ登録ができなくもないのですが、その際は登録時に設定したパスワードを、別手段(手動のメールなど)でユーザに知らせる必要があり、それは手間だろうということで、今回のパターン分けに至りました。

具体的な流れ・注意事項など

それぞれのパターンについて、具体的な流れを記載していきます。前提として、フロントエンドでamplifyを使用できる箇所は積極的に使っています(amplifyのインストール・設定についてはこちら)。
また、今回紹介するのはあくまで上記2パターンの一例であり、もちろんその他の実装パターンもあります。
コードの参考例を記載する箇所は、<バックエンド>、<フロントエンド>のように、どこで記載する処理なのかを記載しています。

管理者として他のユーザを登録するパターン

  1. <バックエンド>ユーザ名を指定して登録(パスワードはcognito側で自動で発行されるので設定不要)
    • 指定するメールアドレスは、登録されるユーザのものを想定しています。
    • 注意すべき箇所は、email_verifiedtrueとしている点です。これを記載しておかないとCognitoのコンソールから見れるE メール確認済みの項目がいいえとなります。この状態だと、パスワード忘れ時の処理などができなくなるようです(メールアドレスが未検証のため、検証コードが送れない)。
import { CognitoIdentityProvider } from "@aws-sdk/client-cognito-identity-provider";

const cognitoIdentityServiceProvider = new CognitoIdentityProvider({
  region: "リージョン名",
});
this.cognitoIdentityServiceProvider.adminCreateUser(
  {
    UserPoolId: "CognitoのユーザプールID",
    Username: "ユーザ名",
    UserAttributes: [
      {
        Name: "email",
        Value: "メールアドレス",
      },
      {
        Name: "email_verified",
        Value: "true",
      },
    ],
  },
);
  1. ユーザのメールアドレスに仮パスワードが送られる

    • この時のCognito上のステータスはFORCE_CHANGE_PASSWORDとなっています。
    • 仮パスワードのデフォルトの有効期限は7日です。変更することも可能です。
  2. <フロントエンド>仮パスワードでログイン&本パスワードの設定

    • ユーザは通常のログイン画面で送られてきた仮パスワードを入力します。
    • 仮パスワードを使ってsignIn関数を呼び出すと、NEW_PASSWORD_REQUIREDの値がuserオブジェクトのchallengeNameに入ってくるので、この時は本パスワードを設定する処理を呼び出すようにします。
import { Auth } from 'aws-amplify';

Auth.signIn(username, password)
.then(user => {
    if (user.challengeName === 'NEW_PASSWORD_REQUIRED') {
        Auth.completeNewPassword(
            user,               
            "新パスワード",
        ).then(user => {
            console.log(user);
        }).catch(e => {
        });
    } else {
        // other situations
    }
}).catch(e => {
});
  1. 本登録完了
    • Cognito上のステータスはCONFIRMEDとなります。

ユーザが自分自身で登録するパターン

  1. <フロントエンド>ユーザ名、パスワードなどを指定して登録
import { Auth } from 'aws-amplify';
async function signUp() {
    const { user } = await Auth.signUp({
        username,
        password,
        attributes: {
            email,
        }
    });
}
  1. ユーザのメールアドレスに検証コードが送られる
    • この時のCognito上のステータスはUNCONFIRMEDとなっています。
    • 検証コードの有効期限は24時間です(こちらは、変更可能という記述が見当たりませんでした)。
  2. <フロントエンド>検証コードとユーザ名を指定して検証
import { Auth } from 'aws-amplify';
async function confirmSignUp() {
  await Auth.confirmSignUp(username, code);
}
  1. 本登録完了
    • Cognito上のステータスはCONFIRMEDとなります。

まとめ

改めて、最初に記載したまとめの表を記載します。

パターン 仮登録時のパスワード要否 仮登録時に使用する関数 仮登録時に送られる情報 使用するケース
管理者として他のユーザを登録するパターン 不要 aws-sdkのadminCreateUser関数(バックエンド) 仮パスワード ユーザの登録を管理者でコントロールしたい業務アプリ
ユーザが自分自身で登録するパターン 必要 amplifyのsignUp関数(フロントエンド)
(aws-sdkのsignUp関数でも可能)
検証コード ユーザが自身で登録可能なコンシューマ向けアプリ

Cognitoを使ったユーザ登録のフローはいろいろやり方があり、どこをバックエンドでやってどこをフロントエンドでやるかを少し悩むかと思いますが、今回記載したフローを1つの参考にしていただければ幸いです。

Discussion