はじめに
本記事では、Cognitoユーザープール内で同一のエイリアスを持つユーザーが存在することをNGとしたい時に、既にプール内に存在するエイリアスを持つユーザを追加をしても、重複エラーが発現せず躓いてしまったので、ログイン属性について解説し、対処方法をシェアします。
この記事は10分程度で読むことができます。
目次
- 問題
- 原因
- 対処
今回発生した問題の原因を、公式ドキュメントのログイン属性を参照して探りながら、対処方法を導きだします。
1.問題
今回起きた問題は、""はじめに""も記載しましたが、以下の通りです。
Cognitoで複数のログイン方法を許容し、ユーザープール内で同一の電話番号を持つユーザーが存在することは
NGとしたい時に、既にプール内に存在する電話番号を持つユーザを追加をしても、
重複してることを知らせるエラー(AliasExistsException ※1)が発現せず、同一の電話番号を持つ
複数のユーザがユーザープールに存在できてしまった。
※1 AliasExistsExceptionは、指定されたエイリアス属性(電話番号やメールアドレスなど)が
既に他のユーザーアカウントに割り当てられている場合に発生するエラー。
Cognitoの設計要件としては以下2つ
- 1つのユーザープール内に同じ電話番号を持つユーザを複数存在させたくない
- ログイン時には電話番号およびメールアドレスでも認証できるようにしたい
今回起こった問題を解決し、この2点を満たすにはどうしたら良いか? という点が今回の焦点になります。
2.原因
まず、原因を探るためにAWS公式ドキュメントから、Cognitoの開発者ガイドに記載されているユーザープール属性の項目を見てみます。
上記のドキュメントを眺めていると、Conigoはログイン属性をカスタマイズできることがわかります。
ログイン属性には、エイリアス属性とユーザ名属性という2つの属性があるようなので、それぞれの特徴をまとめてみます。
1. エイリアス属性
エイリアス属性の設定
- エイリアス属性(電話番号やメールアドレスなど)を設定することで、ユーザーが複数のサインイン方法を利用できる
- たとえば、ユーザーは電話番号でもメールアドレスでもログインできる
重複チェック
- エイリアス属性が設定されている場合、Cognitoはそのエイリアス属性に対してユニーク制約を課さないため、同じ電話番号やメールアドレスを持つ複数のユーザーが存在することができる
- ユーザーの属性がどのように設定されているかによって、重複する属性が検証済みかどうかが異なる場合がある(後から追加した方が検証済みになる)
2. ユーザー名属性
ユーザー名属性の設定
- ユーザー名属性(たとえば、ユーザー名やユーザーID)を設定する場合、電話番号やメールアドレスのどちらか一方だけをサインインに使用できる(どちらもは無理という意味)
重複チェック
- ユーザー名属性に対しては、Cognitoはユニーク制約を課す
→ つまり、電話番号やメールアドレスは重複できず、同じ値を持つ複数のユーザーが存在することは許容されない
要約すると・・・
- エイリアス属性の場合、複数のログイン方法を利用できるが、同一電話番号が複数存在することを許容
- ユーザー名属性の場合、複数のログイン方法を利用できないが、同一電話番号が複数存在することを許容しない
これらより、複数のログイン方法を利用できるようにして、同一電話番号が複数存在することを許容しないという設定方法がCognitoにはないと言えそうです。
3.対処
では、どうするか。
解決方法は、Cognitoの設定はエイリアス属性を選択し、電話番号の重複チェックのロジックはアプリケーション側、つまり、自分で重複検出の処理とそれに基づく適切な処理の実装が必要になります。
これによって、エイリアス属性の重複に対する制約がないことをカバーすることができ、実際に、要件をクリアすることができました。
おわりに
Cognitoのログイン属性を知らないようじゃ無理か。ログイン属性はね、知っとかないと。