どーもどーもどーも。ritou です。 下書きのまま放置してました。
WebAuthnを実サービスに導入しようとしたらどこでつまづくんやってのを考えて来ましたが、ここまではわりと無難な設計に落ち着いている気がします。
- 【ゆるゆるとパスワードレスなUXを検討】(1) WebAuthn Authenticator の登録 - r-weblife
- 【ゆるゆるとパスワードレスなUXを検討】(2) WebAuthn Authenticator でログイン - r-weblife
今回はアカウントを新規登録したタイミングで WebAuthn の Authenticator を登録するあたりを整理します。 と言っても、アカウント作りつつの (1) WebAuthn Authenticator の登録でしかないです。
前提
登場人物を振り返っておきます。
- あるサービス = WebAuthn の RP
- ユーザー = あるサービスに登録完了した時点でこうなっていて欲しいと言う状態
- 1つ以上の User Verification 可能な Authenticator と紐づけられている(MUST)
- 既に確認済のメアド / SMS番号を持っている(SHOULD)
- Authenticator : 生体とかPIN(UserVerification)で単体でユーザー認証が達成できるやつ
新規登録フローってのは、この前提条件に引っ張られてしまうのであまり一般化できなくなってしまいそうなのが悩みどころです。が、仕方ないですね。 そこそこのユーザーデータを扱い、あわよくば決済などを提供できるぐらいのサービスを想定すると、パスワードレスになったとしてもメールやSMSの確認の要件は残るだろうと言うことでこの辺りにしていますが、メアドやSMSの確認を後から行うところもあるよねってとこでその辺りで2パターンを考えていきます。
メアド/SMSの確認を最初に行うフロー
大したことない話ですがサクッと書くとすぐ終わるのでちょっと引っ張ります。
新規アカウント登録のフローとして
- メール/SMSの確認を行う
- 表示名などの必要最低限な設定を行う
みたいなのが一般的かと思います。
今回はそこに
- WebAuthn の Authenticator 登録
というのを追加したいわけですが、入力フォーム一つで済むパスワード設定と異なり、Authenticator 登録はユーザーのアクションを伴うのでタイミングが重要ですね。
- メール/SMSの確認を行う
- 表示名などの必要最低限な設定を行う
- WebAuthn の Authenticator 登録
この順番であれば、ユーザー情報が存在してからの Authenticator 登録みたいな感じですが、今回の前提としては登録完了時に Authenticator が紐づいていて欲しい。 ということは
- 1, 2, 3まで終わったら登録完了!
- 1 が済んだら内部的に仮登録でユーザーID発行、2, 3まで終わったら本登録完了
みたいな作りになるかもしれません。
ResidentKey を用いるログインフローまで考えると、ユーザーIDが振られ、表示名などを登録した後に Authenticator の登録になるのが望ましい気がします。 内部で扱うユーザーIDと Authenticator に渡すユーザーIDを分けるようにしても実現できそうですが、細けぇ話は次回にまとめたいと思います。
次に、ちょっと順番変えてみます。
- メール/SMSの確認を行う
- WebAuthn の Authenticator 登録
- 表示名などの必要最低限な設定を行う
こっちの方がしっくり来る気もします。
これを書きながら思ったことですが、一度 Authenticator に渡してやった user.name
ってメアドやニックネーム的な「後から変更可能な値」が使われることが多そうです。
当然、サービス側で更新した時に Authenticator 側との不整合が起こることは容易に想像できますね。
なんとなく、navigator.credentials.update()
みたいな関数が欲しくない?と思いました。
とりあえず、IDの振り方あたりを気をつければ WebAuthn の Authenticator 登録処理を含む新規登録フローもなんとなく実現できそうです。
後からメアド/SMSの確認を行うフロー
ここでは、メール/SMSの確認処理による "最初の離脱" を抑えるために、確認処理を後から行うサービスを想定します。
この場合、
- 表示名などの必要最低限な設定を行う
と
- WebAuthn の Authenticator 登録
の組み合わせの話になります。 上記、ResidentKey を利用する可能性まで考えると、name or displayName あたりが欲しいので
- 表示名などの必要最低限な設定を行う
- WebAuthn の Authenticator 登録
という順番が無難そうです。
ユーザーがもつ "認証方式の種類" について
builderscon の時も少し話しましたが、メール/SMSを確認して、パスワード認証のリカバリーに使ったりする時点で、もうご立派な認証方式じゃねーかと個人的には捉えています。
今回はその確認を先にやる、後回しにするという2パターンを考えましたが、登録完了時にユーザーが持つ認証方式の数が変わることになります。
特に WebAuthn が使える環境が限られている、ユーザー側の事情により生体認証が不可能な場合などを考慮すると、複数の認証方式が利用できる状態(セキュリティ的観点で言うと利用する認証方式を細かく管理できている状態)になっているのが好ましいでしょう。
「認証する手段がなくなって詰んだ」状態を避けるために、離脱のリスクはありつつも最初にメール/SMSの確認を済ませておくのが無難かな〜と思います。
外部サービスのアカウントを利用した登録フロー
アカウントの新規登録で言うと、いわゆるソーシャルログインを利用した登録フローへの WebAuthn の導入も考えられます。
ソーシャルログインによりSNSなどのいわゆる Identity Provider から確認済みメールアドレスなどを取得できた場合、それをリカバリーに利用できます。
また、ニックネームなどを属性情報の初期値として利用するような実装も一般的でしょう。
WebAuthn の Authenticator 登録との組み合わせ方としては
- ソーシャルログイン
- 表示名などの必要最低限な設定を行う
- WebAuthn の Authenticator 登録
とするのが無難かなと思います。
上述の自前の登録フローと組み合わせる場合は、順番を揃えておくことで実装/UX共に統一感が出せそうですね。
まとめ
今回も無難な内容になったかもしれませんが
- Email / SMS 確認を先にするサービスと後にするサービスがあり、それぞれで WebAuthn Authenticator 登録するタイミングを整理した
- Email / SMS 確認のタイミングはサービスの内容だけではなく、 WebAuthn の認証ができない場合のリカバリー手段としても考慮が必要そう
- ソーシャルログインによる登録に対応している場合も、処理の順番は考える必要がある
これで既存ユーザーへの Authenticator 登録、ログイン、新規登録のUXを整理しました。 次回は今回ちょっとだけ触れた、Authenticator に渡す情報とサービス内のアカウント情報の関係、悩ましい点などを整理したいなと思います。
ではまた!