跳转到内容

能力中的 API

WebOTP API

发布于

WebOTP API 扩展了 Credential Management,让网站请求与自身域名绑定的短信一次性验证码。用户同意后,navigator.credentials.get() 返回 OTPCredential,其中的 code 可填入验证表单(WebOTP API,MDN)。

MDN 将 WebOTP 标为有限可用,并说明它只用于安全上下文。

其兼容性数据记录了桌面版 Chrome 93 和 Android 版 Chrome 84 起支持 OTPCredential,并将支持情况镜像至 Edge、Opera、Samsung Internet 与 Meta Quest Browser;Firefox、Safari 和 Android WebView 记为不支持(WebOTP API,MDN)。保留带 autocomplete="one-time-code" 的输入框可支持手动输入,也让 Safari 提供其独立的短信验证码自动填充(Verify phone numbers on the web with the WebOTP API,Chrome for Developers)。

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

短信末尾必须包含调用方域名和验证码。域名不含协议与端口,绑定域名的这一行必须位于短信末尾(WebOTP API,MDN)。

otp 选项的 transport 必须包含 "sms",可选的 AbortSignal 可取消待处理请求;请求成功后,返回的 OTPCredential 用 code 给出收到的值(WebOTP API,WICG)。

otp-credentials Permissions Policy 指令可禁用该 API。其默认允许列表为 self;策略拦截请求时,Promise 以 SecurityError 拒绝(WebOTP API,MDN)。中止信号触发时请求也可能拒绝,因此输入框和提交按钮仍应可用。

首个示例展示服务端生成的短信格式;另一示例在请求验证码时保留手动验证路径。

以 https://www.example.com 为例,MDN 给出以下短信格式:

Your verification code is 123456.
@www.example.com #123456

空行把说明文字与末尾绑定域名的一行分隔开。

无论 WebOTP 是否存在,此表单都保留标准输入框。用户手动提交会中止待处理的凭据请求。

<form id="otp-form" action="/verify" method="post">
<label>验证码 <input name="code" autocomplete="one-time-code" inputmode="numeric" required></label>
<button>验证</button>
</form>
<script>
const form = document.querySelector('#otp-form');
const input = form.elements.code;
if ('OTPCredential' in window) {
const controller = new AbortController();
form.addEventListener('submit', () => controller.abort(), { once: true });
navigator.credentials.get({
otp: { transport: ['sms'] },
signal: controller.signal,
}).then((otp) => {
input.value = otp.code;
form.requestSubmit();
}).catch(() => {
input.focus();
});
} else {
input.focus();
}
</script>

回退分支聚焦同一输入框,因此不支持该 API 的浏览器仍可走手动验证路径。

规范

规范状态
WebOTP APIWICG 草案