WebOTP API が iframe 内から OTP を受信できるようになりました。
SMS OTP(ワンタイム パスワード)は、認証の 2 つ目のステップとして、またはウェブでの支払いの確認など、電話番号の確認に一般的に使用されます。ただし、ブラウザと SMS アプリを切り替えて OTP をコピー&ペーストまたは手動で入力すると、ミスが生じやすく、ユーザー エクスペリエンスが低下します。
WebOTP API を使用すると、ウェブサイトは SMS メッセージからワンタイム パスワードをプログラムで取得し、アプリを切り替えることなくユーザーのフォームにワンタップするだけで自動的に入力できます。SMS は特別な形式で送信され、送信元にバインドされているため、フィッシング ウェブサイトが OTP を盗む可能性も軽減されます。
WebOTP でまだサポートされていないユースケースの 1 つは、iframe 内のオリジンをターゲットにしていました。これは通常、お支払いの確認(特に 3D セキュアの場合)に使用されます。クロスオリジン iframe をサポートする共通形式を備えた WebOTP API は、Chrome 91 以降、ネストされたオリジンにバインドされた OTP を提供します。
WebOTP API の仕組み
WebOTP API 自体は非常にシンプルです。
…
const otp = await navigator.credentials.get({
otp: { transport:['sms'] }
});
…
SMS メッセージは、送信元にバインドされた 1 回限りのコードをフォーマットする必要があります。
Your OTP is: 123456.
@web-otp.glitch.me #12345
最後の行には、@
で始まるバインド先のオリジンと、#
で始まる OTP が含まれています。
テキスト メッセージが届くと、情報バーがポップアップ表示され、電話番号の確認を求めるメッセージが表示されます。ユーザーが Verify
ボタンをクリックすると、ブラウザは OTP を自動的にサイトに転送し、navigator.credentials.get()
を解決します。ウェブサイトは OTP を抽出して確認プロセスを完了できます。
WebOTP の基本的な使用方法については、WebOTP API を使用してウェブ上で電話番号を確認するをご覧ください。
クロスオリジン iframe のユースケース
支払いシナリオでは、クロスオリジンの iframe 内のフォームに OTP を入力するのが一般的です。一部のクレジット カード発行会社では、支払者の真正性を確認するために追加の確認手順が必要です。これは 3D Secure と呼ばれ、通常、フォームは支払いフローの一部であるかのように、同じページの iframe 内に表示されます。
次に例を示します。
- ユーザーが
shop.example
にアクセスして、クレジット カードで靴を購入します。 - クレジット カード番号を入力すると、統合された支払いプロバイダが iframe 内に
bank.example
のフォームを表示し、ユーザーに電話番号の確認を求めて、迅速な購入手続きを促します。 bank.example
は、OTP を含む SMS をユーザーに送信します。ユーザーは、OTP を入力して本人確認を行うことができます。
クロスオリジン iframe から WebOTP API を使用する方法
クロスオリジン iframe 内から WebOTP API を使用するには、次の 2 つのことを行う必要があります。
- SMS テキスト メッセージで、トップフレームのオリジンと iframe オリジンの両方にアノテーションを付けます。
- クロスオリジン iframe がユーザーから OTP を直接受け取れるように、権限ポリシーを構成します。
デモは https://web-otp-iframe-demo.stackblitz.io で試すことができます。
バウンド送信元を SMS テキスト メッセージにアノテーションする
WebOTP API が iframe 内から呼び出される場合は、SMS テキスト メッセージに、@
の後にトップフレームのオリジン、#
の後に OTP、@
の後に iframe オリジンを含める必要があります。
@shop.example #123456 @bank.exmple
権限ポリシーを構成する
クロスオリジン iframe で WebOTP を使用するには、埋め込み元が otp-credentials の権限ポリシーを介してこの API へのアクセスを許可し、意図しない動作を回避する必要があります。一般的に、この目標を達成するには次の 2 つの方法があります。
- HTTP ヘッダー経由:
Permissions-Policy: otp-credentials=(self "https://bank.example")
- iframe の
allow
属性を介して:
<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>
権限ポリシーを指定する方法のその他の例 をご覧ください。
注意点
ネストのレベル
現在、Chrome では、祖先チェーンに1 つ以下の固有のオリジンを持つクロスオリジン iframe からの WebOTP API 呼び出しのみがサポートされています。次のシナリオでは、
- a.com -> b.com
- a.com -> b.com -> b.com
- a.com -> a.com -> b.com
- a.com -> b.com -> c.com
b.com での WebOTP の使用はサポートされていますが、c.com での使用はサポートされていません。
需要がなく、UX が複雑であるため、次のシナリオもサポートされていません。
- a.com -> b.com -> a.com(WebOTP API を呼び出します)
相互運用性
Chromium 以外のブラウザ エンジンは WebOTP API を実装していませんが、Safari は input[autocomplete="one-time-code"]
をサポートしており、同じ SMS 形式を共有しています。Safari では、送信元に関連付けられた 1 回限りのコード形式を含む SMS が、一致する送信元とともに届くとすぐに、キーボードに OTP を入力するよう提案されます。
2021 年 4 月現在、Safari は %
を使用した一意の SMS 形式の iframe をサポートしています。ただし、仕様の議論で @
を使用することが結論付けられたため、サポートされている SMS 形式の実装が統合されることを願っています。
フィードバック
WebOTP API の改善に役立つ貴重なフィードバックをお寄せください。ぜひ試して、ご意見をお寄せください。
リソース
写真提供: rupixen.com(Unsplash)