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)