帮助用户使用通过短信接收的动态密码
什么是 WebOTP API?
如今,世界上的大多数人都拥有移动设备,而开发者 通常使用电话号码作为其服务用户的标识符。
验证电话号码的方法有很多种,但 通过短信发送的动态密码 (OTP) 是最常见的一种。正在发送此验证码 开发者服务器演示对电话号码的控制。
这一理念已用于许多场景中,旨在实现:
- 用作用户标识符的电话号码。注册新的 服务,有些网站会要求您提供电话号码,而不是电子邮件地址, 将其用作账号标识符。
- 两步验证。登录时,网站要求输入一次性验证码 除密码或其他验证凭据外,通过短信向您发送额外信息 安全性。
- 付款确认。当用户付款时,请求获得 通过短信发送的一次性验证码有助于确认对方的意图。
当前流程会给用户带来不便。在短信中查找动态密码 消息,然后将其复制并粘贴到表单中将会非常麻烦, 关键用户转化历程中的转化率经久不衰 众多大型全球开发者对网络世界的强烈要求。Android 有一个正好可以做到这一点的 API。同样, iOS 版 和 Safari。
借助 WebOTP API,您的应用可以接收绑定到 应用的网域然后,您可以通过编程方式从短信中获取动态密码 消息并验证电话号码。
查看实际案例
假设有一位用户想要通过某个网站验证其电话号码。网站 通过短信向用户发送短信,然后用户输入动态密码 消息,以验证电话号码的所有权。
借助 WebOTP API,用户只需轻点一下即可轻松完成这些步骤, 如视频所示。收到短信后,底部动作条会弹出 并提示用户验证其电话号码。点击验证 按钮,浏览器会将动态密码粘贴到表单中, 表单即可提交,而无需用户按继续。
整个过程如下图所示。
<ph type="x-smartling-placeholder">![](https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe.png?authuser=0000&hl=zh-cn)
亲自尝试演示一下。它不会要求用户提供 您的电话号码或向您的设备发送短信,但您可以从 复制演示中显示的文字,从而在其他设备中使用这行之有效 发件人是谁在使用 WebOTP API 并不重要。
- 在 Chrome 84 或 Chrome 中,转到 https://web-otp.glitch.me 在 Android 设备上提供
- 从另一部手机向您的手机发送以下短信。
Your OTP is: 123456.
@web-otp.glitch.me #12345
您是否收到了短信,并看到了在输入区域输入代码的提示? 这就是 WebOTP API 为用户提供的方式。
WebOTP API 的用法包括三个部分:
- 正确注解的
<input>
标记 - 您的 Web 应用中的 JavaScript
- 通过短信发送的已设置格式的消息文本。
我先介绍 <input>
标记。
为 <input>
标记添加注释
WebOTP 本身无需任何 HTML 注解即可运行,但可以跨浏览器运行
兼容性,强烈建议您将 autocomplete="one-time-code"
添加到
您希望用户输入动态密码的 <input>
标记。
这样一来,Safari 14 或更高版本就会建议用户自动填充 <input>
字段中,输入动态密码。
HTML
<form>
<input autocomplete="one-time-code" required/>
<input type="submit">
</form>
使用 WebOTP API
WebOTP 非常简单,只需复制并粘贴以下代码即可 作业。无论如何,我都会向您介绍一下发生了什么。
JavaScript
if ('OTPCredential' in window) {
window.addEventListener('DOMContentLoaded', e => {
const input = document.querySelector('input[autocomplete="one-time-code"]');
if (!input) return;
const ac = new AbortController();
const form = input.closest('form');
if (form) {
form.addEventListener('submit', e => {
ac.abort();
});
}
navigator.credentials.get({
otp: { transport:['sms'] },
signal: ac.signal
}).then(otp => {
input.value = otp.code;
if (form) form.submit();
}).catch(err => {
console.log(err);
});
});
}
功能检测
特征检测与许多其他 API 的检测相同。正在收听
DOMContentLoaded
事件会等待 DOM 树准备好进行查询。
JavaScript
if ('OTPCredential' in window) {
window.addEventListener('DOMContentLoaded', e => {
const input = document.querySelector('input[autocomplete="one-time-code"]');
if (!input) return;
…
const form = input.closest('form');
…
});
}
处理动态密码
WebOTP API 本身已经足够简单。使用
navigator.credentials.get()
以获取动态密码。WebOTP 会向该方法添加新的 otp
选项。它只有
一个属性:transport
,其值必须是包含字符串 'sms'
的数组。
JavaScript
…
navigator.credentials.get({
otp: { transport:['sms'] }
…
}).then(otp => {
…
在收到短信时,这会触发浏览器的权限流程。如果权限为
返回的 promise 会使用 OTPCredential
对象进行解析。
获取的 OTPCredential
对象的内容
{
code: "123456" // Obtained OTP
type: "otp" // `type` is always "otp"
}
接下来,将动态密码值传递到 <input>
字段。直接提交表单
将省去需要用户点按按钮的步骤。
JavaScript
…
navigator.credentials.get({
otp: { transport:['sms'] }
…
}).then(otp => {
input.value = otp.code;
if (form) form.submit();
}).catch(err => {
console.error(err);
});
…
取消消息
如果用户手动输入动态密码并提交表单,您可以取消
通过使用 options
对象中的 AbortController
实例调用 get()
。
<ph type="x-smartling-placeholder"></ph> JavaScript
…
const ac = new AbortController();
…
if (form) {
form.addEventListener('submit', e => {
ac.abort();
});
}
…
navigator.credentials.get({
otp: { transport:['sms'] },
signal: ac.signal
}).then(otp => {
…
设置短信格式
API 本身看起来应该足够简单,但你应该完成一些事项
该消息必须在以下时间后发送:
调用 navigator.credentials.get()
,并且必须在设备上收到它
其中 get()
被调用。最后,邮件必须遵守以下规则
格式:
- 消息以(可选)人类可读的文本开头,其中包含 4 到 10 最后一行至少包含一个数字的字母数字字符串 输入网址和动态密码
- 调用该 API 的网站的网址的域名部分必须放在其前面
上传者:
@
。 - 该网址必须包含井号(“
#
”),后跟动态密码。
例如:
Your OTP is: 123456.
@www.example.com #123456
以下是不良示例:
格式错误的短信文本示例 | 原因 |
---|---|
Here is your code for @example.com #123456 |
@ 应是最后一行的第一个字符。 |
Your code for @example.com is #123456 |
@ 应是最后一行的第一个字符。 |
Your verification code is 123456 @example.com\t#123456 |
@host 和 #code 之间只能有一个空格。 |
Your verification code is 123456 @example.com #123456 |
@host 和 #code 之间只能有一个空格。 |
Your verification code is 123456 @ftp://example.com #123456 |
不得添加网址架构。 |
Your verification code is 123456 @https://example.com #123456 |
不得添加网址架构。 |
Your verification code is 123456 @example.com:8080 #123456 |
不能包含端口。 |
Your verification code is 123456 @example.com/foobar #123456 |
路径不能包含。 |
Your verification code is 123456 @example .com #123456 |
网域中没有空格。 |
Your verification code is 123456 @domain-forbiden-chars-#%/:<>?@[] #123456 |
网域中没有禁用的字符。 |
@example.com #123456 Mambo Jumbo |
@host 和 #code 应是最后一行。 |
@example.com #123456 App hash #oudf08lkjsdf834 |
@host 和 #code 应是最后一行。 |
Your verification code is 123456 @example.com 123456 |
缺少 # 。 |
Your verification code is 123456 example.com #123456 |
缺少 @ 。 |
Hi mom, did you receive my last text |
缺少 @ 和 # 。 |
演示
通过演示尝试各种消息: https://web-otp.glitch.me
您也可以为它创建分支并创建版本: https://glitch.com/edit/#!/web-otp.
通过跨源 iframe 使用 WebOTP
通常用于将短信动态密码输入到跨源 iframe 中来进行付款 尤其是使用 3D Secure 时。采用支持的通用格式 跨源 iframe,WebOTP API 会提供绑定到嵌套源的动态密码。例如:
- 某位用户访问
shop.example
并使用信用卡买了一双鞋。 - 输入信用卡号后,集成的付款服务机构会显示
用户在 iframe 内从
bank.example
获取表单,要求用户验证自己的 可快速结账的电话号码。 bank.example
会向用户发送包含动态密码的短信,以便他们可以 请输入该验证码来验证自己的身份
如需在跨源 iframe 中使用 WebOTP API,您需要执行以下两项操作:
- 在短信文本中同时注释顶部帧来源和 iframe 来源 消息。
- 配置权限政策以允许跨源 iframe 接收动态密码 由用户直接发送
您可以访问以下网址来试用演示版: https://web-otp-iframe-demo.stackblitz.io.
为短信文本消息添加绑定来源的注释
从 iframe 中调用 WebOTP API 时,短信必须
请依次添加上一帧起始地(后跟 @
)和动态密码 (OTP),以 #
开头
以及最后一行前面加 @
的 iframe 来源。
Your verification code is 123456
@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>
查看有关如何指定权限政策的更多示例 。
在桌面设备上使用 WebOTP
在 Chrome 中,WebOTP 支持监听在其他设备上收到的短信, 可帮助用户在桌面设备上完成电话号码验证。
<ph type="x-smartling-placeholder">此功能要求用户在两个产品上登录同一个 Google 账号 桌面版 Chrome 和 Android Chrome。
开发者只需在其桌面版网站上实现 WebOTP API, 与移动网站上的方法相同,但没有任何特别的技巧: 必填字段。
有关详情,请参阅在桌面设备上使用 WebOTP API 验证电话号码。
常见问题解答
虽然我正在发送格式正确的邮件,但该对话框并未显示。哪里出问题了?
测试该 API 时需要注意以下几点:
- 如果发送者的电话号码包含在接收者的联系人列表中,此 鉴于底层 SMS User Consent API 的设计,该 API 不会触发。
- 如果您在 Android 设备上使用工作资料,并且 WebOTP 能 不起作用,请尝试改为在您的个人资料上安装并使用 Chrome (即您用于接收短信的同一个人资料)。
请返回格式,看看您短信的格式是否正确。
此 API 是否在不同浏览器之间兼容?
Chromium 和 WebKit 已就短信格式达成一致,Apple 宣布 Safari 从 iOS 14 开始支持该格式
和 macOS Big Sur尽管 Safari 不支持 WebOTP JavaScript API
使用默认值 autocomplete=["one-time-code"]
为 input
元素添加注解
如果短信符合规定,键盘会自动建议您输入动态密码
格式
使用短信进行身份验证安全吗?
虽然使用短信动态密码验证电话号码时, 务必谨慎使用短信方式验证电话号码, 因为电话号码可能会被运营商盗用和重复使用。 WebOTP 是一种便捷的重新身份验证和恢复机制, 将其与其他因素(例如知识挑战)相结合,或使用 Web Authentication API 。
在哪里报告 Chrome 实现中的错误?
您在 Chrome 的实现过程中是否发现了错误?
- 通过以下网址报告错误:
https://new.crbug.com.
提供尽可能多的细节信息,提供简单的重现说明,以及
将 Components 设为
Blink>WebOTP
。
我对这项功能有何帮助?
您打算使用 WebOTP API 吗?您的公开支持有助于我们确定各项工作的轻重缓急
并向其他浏览器供应商展示支持这些功能的重要性。
使用 # 标签向 @ChromiumDev 发送推文
#WebOTP
并告诉我们您使用它的地点和方式。