使用 WebOTP API 在跨源 iframe 中填充动态密码表单

WebOTP API 现在可以从 iframe 中接收 OTP。

短信动态密码 (OTP) 通常用于验证电话号码,例如作为身份验证的第二步,或用于验证网络上的付款。不过,在浏览器和短信应用之间切换以复制粘贴或手动输入 OTP 会很容易出错,并会影响用户体验。

借助 WebOTP API,网站能够以编程方式从短信中获取动态密码,并只需一键即可自动在表单中为用户输入该密码,而无需切换应用。短信采用特殊格式并绑定到来源,因此也降低了钓鱼式网站窃取动态密码的几率。

WebOTP 尚不支持的一种用例是定位到 iframe 内的源。这通常用于付款确认,尤其是在使用 3D Secure 时。从 Chrome 91 开始,WebOTP API 现在采用支持跨源 iframe 的通用格式,可提供绑定到嵌套源的 OTP。

WebOTP API 的运作方式

WebOTP API 本身非常简单:

…
  const otp = await navigator.credentials.get({
    otp: { transport:['sms'] }
  });
…

短信必须采用与来源绑定的一次性密码的格式

Your OTP is: 123456.

@web-otp.glitch.me #12345

请注意,最后一行包含要绑定的来源(前面带有 @),后跟前面带有 # 的 OTP。

短信到达后,系统会弹出一个信息栏,提示用户验证其电话号码。用户点击 Verify 按钮后,浏览器会自动将 OTP 转发到网站并解析 navigator.credentials.get()。然后,网站可以提取 OTP 并完成验证流程。

如需了解使用 WebOTP 的基础知识,请参阅使用 WebOTP API 在网络上验证电话号码

跨源 iframe 用例

在跨源 iframe 中的表单中输入 OTP 在付款场景中很常见。某些信用卡发卡机构会要求您完成额外的验证步骤,以检查付款人的真实性。这称为 3D 安全,该表单通常会显示在同一网页上的 iframe 中,就像是付款流程的一部分一样。

例如:

  • 用户访问 shop.example,使用信用卡购买一双鞋子。
  • 输入信用卡号后,集成的付款服务提供商会在 iframe 中显示 bank.example 中的表单,要求用户验证其电话号码以便快速结账。
  • bank.example 向用户发送包含 OTP 的短信,以便用户输入该 OTP 来验证其身份。

如何从跨源 iframe 使用 WebOTP API

如需在跨源 iframe 中使用 WebOTP API,您需要执行以下两项操作:

  • 为短信文本消息中的顶级框架来源和 iframe 来源添加注释。
  • 配置权限政策,以允许跨源 iframe 直接从用户接收 OTP。
iFrame 中的 WebOTP API 在运行中。

您可以访问 https://web-otp-iframe-demo.stackblitz.io 自行试用演示。

为短信添加绑定来源注释

从 iframe 内调用 WebOTP API 时,短信文本消息必须包含前面带有 @ 的顶级框架源,后跟前面带有 # 的 OTP,再后跟前面带有 @ 的 iframe 源。

@shop.example #123456 @bank.exmple

配置权限政策

如需在跨源 iframe 中使用 WebOTP,嵌入者必须通过 otp-credentials 权限政策授予对此 API 的访问权限,以避免意外行为。通常,有两种方法可以实现此目标:

  • 通过 HTTP 标头:
Permissions-Policy: otp-credentials=(self "https://bank.example")
  • 通过 iframe allow 属性:
<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>

请参阅有关如何指定权限政策的更多示例

注意事项

嵌套级别

目前,Chrome 仅支持从其祖先链中不超过一个唯一源的跨源 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 中使用。

请注意,由于需求不足和用户体验复杂性,我们也不支持以下场景。

  • a.com -> b.com -> a.com(调用 WebOTP API)

互操作性

虽然 Chromium 以外的浏览器引擎不实现 WebOTP API,但 Safari 支持 input[autocomplete="one-time-code"],因此采用了相同的短信格式。在 Safari 中,只要收到包含与匹配来源相关联的一次性验证码格式的短信,键盘就会建议您在输入字段中输入 OTP。

自 2021 年 4 月起,Safari 支持使用 % 的唯一短信格式的 iframe。不过,由于规范讨论得出的结论是改用 @,因此我们希望支持的短信格式的实现会趋于一致。

反馈

您的反馈对改进 WebOTP API 至关重要,因此请继续试用,并告诉我们您的想法。

资源

照片由 rupixen.comUnsplash 上发布