短信验证码自动填充:Android、iOS与网页格式指南
讲解Android、iOS和网页上的验证码自动填充:SMS Retriever哈希、域名绑定验证码、WebOTP、适用三端的统一短信格式,以及WhatsApp自动填充。
作者: OmniChannels.ai Editorial Team · 审阅: BroadNet Messaging Solutions Team
集成
简短回答
验证码自动填充由三种相互独立的机制构成。Android应用使用SMS Retriever API,短信不超过140字节并带11位应用哈希;或使用无需哈希的SMS User Consent API。iOS直接从短信中识别验证码,域名绑定验证码的末行形如@example.com #123456。网页使用autocomplete="one-time-code"和WebOTP API,读取同样的末行。
本页内容
要点速览
- Android有两种API:SMS Retriever(短信不超过140字节,含一次性验证码和11位应用哈希)和SMS User Consent(由用户批准共享一条短信)。
- 在iOS上,把输入框设为one-time-code内容类型;域名绑定验证码的末行是@域名、一个空格和#验证码,自iOS 14起支持。
- 在网页上,为输入框添加autocomplete="one-time-code",并为Android上的Chrome调用带sms传输方式的navigator.credentials.get;Safari使用该属性。
- 只要把应用哈希放在末行@域名 #验证码之上,一条短信就能同时满足三端,但请在真机和实际运营商上测试。
- WhatsApp身份验证模板提供复制验证码、一键和零点击按钮;零点击仅支持Android。
本指南面向希望验证码在Android、iPhone和网页上自动填入的开发者与产品负责人。内容说明各平台对短信有何要求、如何写出一条适用于三端的短信、WhatsApp身份验证模板如何处理自动填充,以及常见的出错原因。
各平台的验证码自动填充如何工作?
各平台读取短信的方式不同,所以没有统一的开关。Android需要应用哈希或用户同意,iOS自行识别验证码,浏览器则读取格式化的末行。
| 平台 | 机制 | 短信需要什么 | 用户操作 |
|---|---|---|---|
| Android应用 | SMS Retriever API | 不超过140字节,含一次性验证码和11位应用哈希 | 无 |
| Android应用 | SMS User Consent API | 含一次性验证码的短信 | 批准共享一条短信 |
| iOS和iPadOS应用 | 安全码自动填充 | iOS能识别的验证码;建议使用域名绑定格式 | 点击建议项 |
| 网页(Safari) | autocomplete="one-time-code" |
域名绑定的末行 | 点击建议项 |
| 网页(Android上的Chrome) | WebOTP API | 末行为@host #code |
确认提示 |
这一切的前提是短信能送达。如果收不到,请参阅收不到验证码。
Android的SMS Retriever API如何工作?
您的应用请Google Play服务监听一条短信,短信中带有标识您应用的哈希。无需额外的应用权限。
Google的文档列出了验证短信的三项要求。短信必须:
- 不超过140字节;
- 包含一个一次性验证码,由您的应用回传给服务器以完成验证;
- 包含一个标识您应用的11位哈希字符串。
短信的其余内容由您决定。流程是:应用在请求短信的同时启动API,服务器发送短信,Play服务把它转交给您的应用,应用提取验证码并回传服务器校验。服务器还应检查验证码是否有效、是否已过期。
如何获得11位哈希?
Google称,该哈希是base64编码哈希的前11个字符。它由您应用的签名证书计算得出,使用Google文档中的keytool步骤。如果由Google Play管理应用签名,请导入该证书来计算;如果您自行签名,请使用生产密钥库和证书别名。
由于哈希取决于签名证书,用不同密钥签名的构建会有不同的哈希。用调试版本测试生产环境短信时请考虑到这一点,并为您发布的每种签名配置确认哈希。
不想管理哈希怎么办?
使用SMS User Consent API。Google的文档称,在共享短信之前会先询问用户,随后整条短信对您的应用可见,由应用解析出验证码。按Google页面所述,短信必须包含一个4至10位、至少含一个数字的字母数字串,监听持续五分钟,还可以选择限定发件人。请在短信到达之前启动该API:更早收到的短信不会被转发。
iOS和iPadOS如何自动填充验证码?
iOS会识别含一次性验证码的短信,并在声明为验证码输入框的字段中提供该验证码。Apple文档为您列出两个步骤。
- 设置输入框的内容类型。在UIKit中,把
textContentType设为.oneTimeCode;在SwiftUI中,使用同值的textContentType修饰符。对于网站,在输入框上设置autocomplete="one-time-code"。 - 可选:把验证码绑定到您的域名。自iOS 14和macOS Big Sur起,Apple允许您按特定格式编写短信,使自动填充仅在Safari网站或应用的关联域名匹配时才建议该验证码。这使人更难被诱骗到钓鱼网站上输入验证码。
按Apple文档的格式:前面是任意文字,然后末行是以@开头的域名、一个空格,以及以#开头的验证码。
Your Example code is 123456.
@example.com #123456
对于应用,请把绑定的域名加入应用的关联域名,否则自动填充不会建议它。没有绑定的标准验证码仍会被识别,但Apple推荐使用域名绑定格式。
网页上的验证码自动填充如何工作?
先添加属性,再为支持的浏览器添加JavaScript。
<input type="text" inputmode="numeric"
autocomplete="one-time-code" name="otp" />
Chrome的文档推荐使用该属性以实现跨浏览器兼容,并指出Safari虽然没有WebOTP的JavaScript API,但会用它从格式正确的短信中建议验证码。
对于Android上的Chrome,请用sms传输方式调用WebOTP。该API需要安全来源(HTTPS),并且可以用AbortController在用户手动输入验证码时取消待处理的请求。
if ("OTPCredential" in window) {
const ac = new AbortController();
const form = document.querySelector("form");
const input = document.querySelector("input[autocomplete=one-time-code]");
form.addEventListener("submit", () => ac.abort());
navigator.credentials
.get({ otp: { transport: ["sms"] }, signal: ac.signal })
.then((otp) => {
input.value = otp.code;
form.submit();
})
.catch(() => {}); // user dismissed, or no matching SMS
}
短信必须遵循WICG规范和Chrome指南中的来源绑定格式:末行之前有一个由四到十位字母数字组成、至少含一个数字的验证码,末行以@开头,后跟主机、一个空格,以及#加验证码。主机中不得含有空白字符。
一条短信能同时适用于Android、iOS和网页吗?
通常可以,因为这些规则相互兼容。把便于阅读的文字放在最前,把Android哈希放在结尾之上的一行,把域名绑定行放在最后。这种排布是根据文档规则推导的,并非厂商保证,所以请测试。
Your Example code is 483921. Do not share it.
Ab3dE+9xYz1
@example.com #483921
为什么是这个顺序:Apple和网页规范都要求域名和验证码在末行。Google要求短信中某处含有11位哈希,但在我们查阅的页面中并未限定其位置。上面的示例以纯拉丁字符计为78字节,远低于140字节的限制。
上线前的检查清单:
- 验证码是单独一个词元,与文本中的其他数字清晰分开。
- 末行的域名与网站及应用的关联域名一致。
- Retriever版本的总长度在140字节以内。
- 哈希与被测构建的签名密钥一致。
- 在每个平台的真机上,并通过您实际使用的运营商完成测试。
阿拉伯语和Unicode文本怎么办?
让验证码和两个机器可读的部分保持朴素。Google的限制按字节计算,而Unicode短信单条能容纳的字符远少于GSM-7:单段分别为70个和160个(参见短信字符限制与Unicode)。因此一句阿拉伯语会很快耗尽额度,只要有一个非GSM字符,整条短信就会切换为Unicode。
稳妥的做法:验证码使用拉丁数字,@域名 #验证码使用ASCII,阿拉伯语文字尽量简短。我们没有找到描述其他数字体系书写的验证码如何自动填充的官方文档,所以不作说明,并建议使用前先测试。
WhatsApp身份验证模板如何处理自动填充?
Meta的身份验证模板有三种按钮样式,每种都带有<code> is your verification code.形式的固定正文。
| 按钮 | 作用 | 说明 |
|---|---|---|
| 复制验证码 | 用户点击复制验证码,再粘贴到您的应用中 | 无需改动应用 |
| 一键自动填充 | 在Android上,按钮打开您的应用并传入验证码 | 需要在supported_apps中提供package_name和signature_hash |
| 零点击 | 没有按钮;WhatsApp客户端把验证码广播给您的应用 | 仅限Android;您必须接受Meta的零点击条款 |
Meta的文档还指出,在iOS 26及更高版本上,键盘建议无需任何集成即可提供自动填充,而在不支持零点击的平台上,用户会收到复制验证码按钮。您可以用code_expiration_minutes设置有效期,预览API接受1至90分钟的值。两种渠道的对比见WhatsApp验证码与短信验证码。
实例:网约车应用登录
“Qafila Rides”(虚构)有Android应用、iOS应用和位于qafila.example的移动网站。
- 用户点击“发送验证码”时,Android应用启动SMS Retriever。
- 后端生成一个有效期为几分钟的六位验证码,并通过短信API发送上面的三行短信。
- Android把短信交给应用。iOS在键盘上方提供验证码。在移动网站上,Safari给出建议,Chrome通过WebOTP填入。
- 服务器只校验该验证码一次,拒绝重复使用和已过期的验证码,并限制请求频率。
- 如果短信在较短的超时时间内未得到确认,后端会提供WhatsApp身份验证模板作为第二条路径。
常见错误有哪些?
- 验证码不单独出现。 验证码旁边多出其他数字(电话、价格、日期)会干扰识别。每条短信只放一个验证码。
- 哈希错误。 哈希随签名证书而变。调试密钥生成的哈希与生产构建不匹配。
- 域名不一致。
@example.com必须与网站或关联域名一致,否则iOS和WebOTP不会提供验证码。 - 末行被破坏。
#验证码之后有任何内容、缺少空格,或域名中含有空白,都会破坏格式。 - 短信过长或Unicode过多, 超出140字节的Retriever限制。
- 监听过晚。 User Consent API会忽略在启动之前收到的短信。
- 把自动填充当作安全措施。 自动填充只是便利。仍须在服务器端校验、让验证码过期并限制尝试次数,同时留意短信泵送欺诈。
- 适用范围。 本指南涵盖撰写时文档所述的行为。平台规则会变化,发布前请查阅所附来源。
关于短信措辞和有效期的选择,请参阅我们的验证码与身份验证消息指南。
OmniChannels.ai如何提供帮助
OmniChannels.ai通过BroadNet的运营商直连发送短信和WhatsApp验证码,让您能够掌控自动填充格式所依赖的确切短信文本。WhatsApp模板涵盖复制验证码、一键和零点击身份验证。渠道回退(例如先WhatsApp后短信)可按使用场景配置,送达状态以统一的Webhook格式送达。请参阅短信API文档、WhatsApp API文档和验证码解决方案。
常见问题
SMS Retriever API的短信格式是什么?
Google的文档称,短信不得超过140字节,须包含一个由您的应用回传给服务器的一次性验证码,并含有标识您应用的11位哈希。除此之外,内容由您决定。该哈希让Google Play服务无需额外权限即可把短信送达正确的应用。
SMS User Consent API需要应用哈希吗?
Google对SMS User Consent API的概述中没有提到应用哈希。用户会看到一个提示,并选择是否把这条短信共享给您的应用。您的应用必须在短信到达之前开始监听,然后从短信正文中自行提取验证码。
iOS上的域名绑定短信验证码是什么?
这是一条末行把验证码绑定到您域名的短信:域名前加@,一个空格,再加以#开头的验证码。Apple文档说明它适用于iOS 14及更高版本。只有当Safari中的网站或应用的关联域名与短信中的域名一致时,自动填充才会建议该验证码。
WebOTP如何读取短信?
页面调用带otp选项和sms传输方式的navigator.credentials.get。当收到末行为@主机 #验证码、且主机与页面来源一致的短信时,浏览器会请用户确认并返回验证码。它需要HTTPS,文档中明确支持的浏览器是Android上的Chrome。
为什么我的验证码无法自动填充?
常见原因包括:验证码不够清晰可辨、Android上应用哈希错误或缺失、末行不符合@域名 #验证码格式、域名与页面不匹配,或文字过长使短信超出字节限制。请对照格式规则逐项检查,再用真机测试。
WhatsApp支持验证码自动填充吗?
支持。Meta的身份验证模板支持复制验证码按钮、一键自动填充按钮和零点击选项。一键和零点击需要您的Android包名和签名哈希。零点击仅支持Android,其他平台的用户会收到复制验证码按钮。
资料来源
- SMS Retriever API: perform SMS verification — Google for Developers
- SMS User Consent API: request a one-time code — Google for Developers
- Enabling AutoFill for domain-bound SMS codes — Apple Developer
- Verify phone numbers on the web with the WebOTP API — Chrome for Developers
- WebOTP API — WICG specification
- Authentication templates — WhatsApp Business Platform, Meta for Developers
继续阅读
更多指南集成
E.164手机号格式:转换与校验方法
E.164手机号格式详解:格式规则、本地号码转换示例表、WhatsApp与短信API的要求、正则表达式和libphonenumber校验方法。
9 分钟阅读
集成
短信API发送示例:Python、Node.js、PHP与cURL
用API发送短信的Python、Node.js、PHP和cURL示例:单条与批量发送、Unicode与阿拉伯语、分段计数、送达状态Webhook以及错误处理,开发者可直接复制使用。
10 分钟阅读
WhatsApp
WhatsApp验证码与短信验证码:成本、送达与回退
WhatsApp验证码与短信验证码对比:成本模型、送达率、用户体验、身份验证模板、WhatsApp到短信的回退设计,以及防刷与反欺诈控制,帮助出海产品选对验证渠道。
10 分钟阅读
