サービスの新規登録とログインを分けるかまとめるかの考え方
ritouです。
Digital Identity技術勉強会 #iddance Advent Calendar 2021 の18日目の記事です。(代わりに書いた)
今回のお話は
- 新しいサービス作る時とか、登録/ログインフロー考えるよね?考えない?おじさんそう言うお仕事してるの
- パスワードレスな認証方式やID連携とか使いだすと、登録もログインも一緒でええかみたいな話も出てくるでしょ?こない?おじさんとこは出るの
- 分けたまま、一緒にする場合にそれぞれ気をつけないといけないことを整理しましょ
というお話です。
1. パスワード認証時代は分けてりゃ良かった
パスワード認証の場合、新規登録とログインでUXの要件が異なります。
- 新規登録 : ユーザーが主張する識別子や連絡先としてメールアドレスやSMS番号を確認し、パスワードを登録させる
- ログイン : ユーザーが主張する識別子とパスワードを入力させて検証する
当然気をつけなければならない点はありますが、新規登録/ログイン画面が別になっていることは一般的です。
2. ワンタイムパスワードやID連携のフロー
これが、最近のパスワードを使わない認証方式となると少し話が変わってきます。
- SMS/EメールでOTPを送信、受信して検証する
- ID連携により外部IdPのアカウント情報を利用する
これらの処理は新規登録/ログイン共に意味合いは異なりつつも "途中までは" 同じUXとなります。
- 新規登録
- 未登録のSMS番号/メールアドレスにOTPを送信し、検証する。その後、必要な属性情報などを登録させたりしてログインセッションを発行。
- 未連携の外部アカウント情報をIdPから受け取る。その後、必要な...(略)
- ログイン
- 登録済みのSMS番号/メールアドレスにOTPを送信し、検証する。成功したらログインセッションを発行。
- 連携済みの外部アカウント情報をIdPから受け取る。その後、ログインセッションを発行。
このように新規登録/ログインを分けた場合に扱いに困るのは、次のようなケースです。
- 新規登録フローに登録済みのSMS番号/メールアドレスを突っ込まれる
- 新規登録フローで連携済みの外部アカウント情報をIdPから受け取る
- ログインフローに未...(略)
この場合、「あなたは既に登録済みです」「あなたはまだ登録されていません」とエラーを表示して、全く同じフローをやり直させるところも見かけますが、ユーザーは結局同じことをさせられることになるので、ちょっと避けたいところです。
もう少し考えて
- SMS/Emailの確認は大丈夫だったけど未登録だったので新規登録フローの途中から続けさせる
- 逆に登録済みだったのでログインさせちゃおう
といったフローを跨いだ処理を実装しているところも見られますが、パスワード認証のような分けた方が良いパターンが存在しない場合は 「新規登録/ログイン」の最初のフローを共通化しよう と言う考え方が出てくるわけです。
最初にSMS/Emailの確認やID連携を行い、
- 未登録だったら必要な属性情報の登録フローへ
- 登録済みであればセッション発行へ
と言うように分岐する方式が出てくるわけです。
5. 複数の認証方式を採用している場合の混乱
本質からはずれますが、複数の認証方式を採用しているときにフローを分けてもまとめても残ってしまう課題があります。
「同一ユーザーが複数の認証方式で新規登録をしてしまう問題」です。
- 既に確認済みのEmailがgmailアドレスであり、GoogleアカウントとのID連携したらユーザー情報に含まれていた
みたいな時にどのような実装をしたら良いでしょうか?
- 確認済みだし同じユーザーとして扱う
- ID連携において、メールアドレスをキーにした処理はアンチパターンですぞ?
- 確認済みメアドとはいえ、時間が経っていたら別のユーザーに紐づいている可能性も否定はできない
- 再度手動でリンクやOTPを送って確認できたら同一ユーザーとして扱う 個人的にはこの辺りでやりたい
- 別のユーザーとして扱い、メールアドレスにユニーク制約がある場合はまた考える
みたいな細かい話が出てくるかもしれません。
この話だけでも1記事かけそうなので暇になったら書きます。
6. FIDOだとどうなる?
ここまでの流れで「パスワードレス時代は新規登録/ログインのフローは統合されるのか」と思われた方もいらっしゃるかもしれませんが、WebAuthnなどのFIDO認証を利用する場合はちょっと考える必要があります。
- Authenticator の登録
- Authenticator による認証
と言う2つの処理が分かれていること、そして認証機能についても
- ユーザーを識別して紐づけられている公開鍵での認証を要求
- ユーザーを識別しないで認証を要求(いわゆるResidentKey,最近はClient-side discoverableなんとかだったか)
と言った方式があるため、仕様特徴とサポート状況を組み合わせでその時点で良さげなUXを提供していく必要があるでしょう。
このあたりの話も機会があれば別途整理しましょう。
まとめ
色々書きましたがお伝えしたかったのは
- パスワード認証時代は別で良かった
- フローの最初にやることが同じならまとめられる
ぐらいですかね。
ではまた!
Discussion