有关短信动态密码表单的最佳做法

了解如何优化短信动态密码表单并改善用户体验。

要求用户提供通过短信发送的动态密码(动态密码)是一种常见的做法 确认用户电话号码的方式。以下是短信动态密码的几个用例:

  • 双重身份验证。除了用户名和密码之外,您还可以使用短信动态密码 可明确表明相应账号归收到 通过短信发送的动态密码。
  • 电话号码验证。有些服务会将电话号码用作用户的 主要标识符。在此类服务中,用户可以输入自己的电话号码和 通过短信接收的动态密码来证明其身份。有时需要与 PIN 码组合使用 构成双重身份验证。
  • 账号恢复。如果用户失去对其账号的访问权限,则需要: 进行恢复。向其注册的电子邮件地址发送电子邮件,或 向手机号码发送短信是常用的账号恢复方法。
  • 付款确认 在付款系统中,某些银行或信用卡 出于安全考虑,发卡机构请求付款人进行额外的身份验证。 短信动态密码通常用于此目的。

此博文介绍了针对上述用途构建短信动态密码表单的最佳做法 案例

核对清单

要通过短信动态密码提供最佳用户体验,请按以下步骤操作:

  • <input> 元素与以下内容搭配使用: <ph type="x-smartling-placeholder">
      </ph>
    • type="text"
    • inputmode="numeric"
    • autocomplete="one-time-code"
  • 使用 @BOUND_DOMAIN #OTP_CODE 作为动态密码短信的最后一行。
  • 使用 WebOTP API

使用 <input> 元素

使用包含 <input> 元素的表单是您应执行的 因为它适用于所有浏览器。即使其他建议来自 此帖子在某些浏览器中不可用,用户仍可输入并提交动态密码 。

<form action="/verify-otp" method="POST">
  <input type="text"
         inputmode="numeric"
         autocomplete="one-time-code"
         pattern="\d{6}"
         required>
</form>

下面几个技巧可确保输入字段充分发挥 浏览器功能。

type="text"

由于动态密码通常为五位或六位数字,因此使用 输入字段的 type="number" 看似直观,因为它会更改 仅通过键盘输入数字。我们不建议您这样做,因为浏览器 为一个可数数字,而不是多个数字的序列, 这可能会导致意外行为使用 type="number" 会导致上下运行 显示在输入字段旁边的按钮;按这些按钮 递增或递减数字,并且可以移除前面的零。

请改用 type="text"。此操作不会将手机键盘变成数字 但没关系,关于使用 inputmode="numeric" 的下一条提示 作业。

inputmode="numeric"

使用inputmode="numeric" 将手机键盘更改为纯数字键盘。

有些网站为动态密码输入字段使用 type="tel",因为它也 在以下情况下,将手机键盘仅显示为数字(包括 *#) 重点。这项黑客操作过去曾在inputmode="numeric" 没有得到广泛支持。自 Firefox 开始支持 inputmode="numeric", 也无需使用语义不正确的 type="tel" 黑客手段。

autocomplete="one-time-code"

autocomplete 属性可让开发者指定 必须提供自动补全帮助,并告知浏览器 字段中预期的信息类型。

使用 autocomplete="one-time-code",每当用户在 表单打开时,操作系统会启发式解析短信中的动态密码, 键盘会推荐动态密码供用户输入。它仅适用于 Safari 12 和 但我们强烈建议您使用它 在这些平台上改善短信动态密码体验的简单方法。

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
`autocomplete="one-time-code"` 的实际运用。

autocomplete="one-time-code" 可提升用户体验,但还有更多精彩 做法是确保短信符合源于来源的消息要求, 格式

设置短信文字的格式

通过与 通过短信传送的与来源绑定的一次性验证码 规范

格式规则很简单:在短信末尾添加接收者域名 以 @ 开头的动态密码,以 # 开头的动态密码。

例如:

Your OTP is 123456

@web-otp.glitch.me #123456

使用标准格式的动态密码信息可进行提取 更简便、更可靠的代码。将动态密码与 使用户更难向恶意网站提供代码。

使用这种格式有以下几项好处:

  • 动态密码将与网域绑定。如果用户所在的网域不是 短信中指定的验证码,则系统不会显示动态密码建议。 这样也能降低钓鱼式攻击和潜在的账号盗用风险。
  • 现在,浏览器无需依赖 神秘而易断的启发法。

当网站使用 autocomplete="one-time-code"、iOS 14 或更高版本的 Safari 时 将按照上述规则建议动态密码。

这种短信格式对 Safari 以外的浏览器也有益。Chrome、Opera、 Android 上的 Vivaldi 也支持与来源绑定的一次性代码规则, WebOTP API,但不是通过 autocomplete="one-time-code"

使用 WebOTP API

WebOTP API 可让您访问动态密码 。通过调用 navigator.credentials.get() otp 类型 (OTPCredential),其中 transport 包含 sms,即网站 将等待符合来源绑定一次性验证码的短信 由用户提供并授予访问权限将动态密码传递到 JavaScript 后 网站可以在表单中使用它,也可以将其直接 POST 到服务器。

navigator.credentials.get({
  otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
WebOTP API 的实际应用。

如需详细了解如何使用 WebOTP API,请参阅在网络上验证电话号码 。 或复制并粘贴以下代码段。( 请确保 <form> 元素的 actionmethod 属性已正确设置。)

// Feature detection
if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    // Cancel the WebOTP API if the form is submitted manually.
    const ac = new AbortController();
    const form = input.closest('form');
    if (form) {
      form.addEventListener('submit', e => {
        // Cancel the WebOTP API.
        ac.abort();
      });
    }
    // Invoke the WebOTP API
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
      input.value = otp.code;
      // Automatically submit the form when an OTP is obtained.
      if (form) form.submit();
    }).catch(err => {
      console.log(err);
    });
  });
}

摄影:Jason Leung 不启动