AWS Cognitoを使用して、ユーザー名、メール、電話番号で認証する方法

AWS Amplifyには、こちらに記載されているように、Amplify CLIを介してインストールできる認証サービスがあります。

しかしCLIが提供するオプションには問題があり、以下の4つのうち1つを選択するしかありません:

  1. ユーザー名
  2. メール
  3. 電話
  4. メールまたは電話(これは最初にログインしたオプションに設定されます -> メールまたは電話)

アプリ開発者としては、ユーザーに常にメールまたは電話を通じてログインするオプションを提供したいと考えます(ユーザー名はもはや意味を成しません)。

Amplifyを使用せずにCognitoを直接設定した場合、以下のオプションを使用してこの設定を行うことが可能です:

Amplifyでは既存のCognitoユーザープールをインポートするオプションを提供していますが、その場合にはライフサイクル、設定、ユーティリティが利用できません。つまり、いくつかの機能を得るためにはいくつかの機能を失います。

しかし、AWSが提供しているoverrideオプションという機能を使うと、両方のベストを得ることができます。このオプションはoverride.tsファイルを生成し、Cognitoオプションの詳細を設定することを可能にします。

したがって、メールでのログインと電話でのログインの両方を可能にするという私たちの要件に対しては、override.tsに以下のコードを追加する必要があります。そしてファイルは以下のようになります:

import { AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyAuthCognitoStackTemplate) {
  resources.userPool.aliasAttributes = ['email', 'phone_number',];
}

これを追加すると、Amplifyは正しいサインインオプションを持つCognitoユーザープールを構築します:

サインアップは以下のようになります:

const response = await Auth.signUp({
  username: v4(),
  password: password,
  attributes: {
    email: email, // これを渡す
    phone_number: phone,// またはこれ
  },
})

携帯電話番号の属性を追加するには、以下のようにします:

async function addPhone(phone: string) {
  try {
    const user = await Auth.currentAuthenticatedUser()
    const responseUpdate = await Auth.updateUserAttributes(user, {
      phone_number: phone,
    })
    console.log({responseUpdate})
  } catch (error) {
    console.error('error adding phone:', error)
  }
}

電話を使ってログインするには、以下のようにします:

async function loginPhone(phone: string) {
  try {
    const authUser = await Auth.signIn(phone, password)
    console.log({authUser})
  } catch (error) {
    console.error('error logging in:', error)
  }
}

リポジトリはこちらです。
以下の機能はCognitoユーザープールの設定をテストするために利用できます:

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/bnjr/authentication-with-username-email-and-phone-using-aws-cognito-2e2b