用途
本技能面向已经使用 Twilio Programmable Messaging API 自建 OTP(一次性验证码)流程的开发者,指导其将整套逻辑迁移到 Twilio Verify。自建方案通常需要手动完成:生成随机验证码、将验证码与手机号及过期时间写入数据库、通过自有号码发送短信,之后再由自己查询、比对并检查过期。Verify 用两次 API 调用替代上述全部工作,并额外提供 Fraud Guard(短信泵送防护)、托管发送号码池和自动 A2P/合规处理。
主要能力
迁移后,以下自建组件被 Verify 替代:
- 购买/管理发送号码或 Messaging Service → 按国家自动选择的托管发送号码池(短码/长码、免费电话、字母 ID)。
- 随机验证码生成 → 内置生成(4–10 位,默认 6 位)。
- 存储验证码、手机号、过期时间的数据库表 → 无状态,Verify 自行跟踪验证码与 10 分钟过期。
- 自定义重发限流/尝试计数 → 内置速率限制(每个号码每 10 分钟 5 次发送与 5 次校验)。
- 短信泵送/欺诈过滤 → Fraud Guard(地理权限、速率异常),一键启用。
- OTP 号码的 A2P 10DLC 活动注册 → 豁免,Verify 流量无需 10DLC 活动。
- 按渠道分别集成(短信、语音、WhatsApp 等)→ 单一 API,只需更改 channel 参数。
- 本地化消息文案 → 数十种语言的预审模板,按国家自动解析。
使用方式
前置条件:已有的 Programmable Messaging OTP 实现、Twilio 账户、环境变量 TWILIO_ACCOUNT_SID、TWILIO_AUTH_TOKEN、VERIFY_SERVICE_SID,以及 SDK(pip install twilio / npm install twilio)。Verify 无需单独激活产品,只需创建一个 Service。
迁移步骤:
-
一次性创建 Verify Service,保存返回的 SID。friendlyName 会出现在默认验证短信中(如“Your Acme verification code is 123456”),应设为业务名称而非内部标签;名称中避免嵌入 5 位及以上数字,否则可能触发错误 60200。
-
发送验证:调用 verifications.create,传入 to 和 channel。Verify 会生成验证码、以 10 分钟过期跟踪并通过托管发送方投递。status 为 pending 表示验证码已发出。无需生成验证码、写数据库或自有号码。切换渠道只需将 channel 改为 "call"、"whatsapp" 或 "email"(也支持 "sna" 和 "auto")。RCS 不是 channel 取值——Verify 会在设备支持时将 sms 验证升级为 RCS,并自动回退到 SMS。
-
校验验证码:调用 verification_checks.create,传入 to 和 code。status 为 "approved" 时放行,否则拒绝("pending" 表示错误或尚未提交,"expired" 表示超过 TTL)。错误验证码不会抛异常,而是返回 status: "pending",必须显式判断 status === "approved"。通过后验证为一次性,再次校验返回 404。流量完全迁移后可删除 OTP 数据库表。
关键模式:
- 号码必须为 E.164 格式(Verify 严格校验)。若数据库存储的是国家格式号码,发送前需规范化,否则会得到错误 60200。可用 Lookup API 将用户输入转换为 E.164 并获取 ISO 国家代码。
- 自带验证码(bring-your-own OTP):若无法立即移除现有生成逻辑,可通过 custom_code 传入验证码,让 Verify 仍负责投递、模板和本地化。注意事项:需按 Service 启用(默认关闭),通过 API 创建/更新 Service 时设置 CustomCodeEnabled=true,或在控制台开启“Enable Custom Verification Code”;不要传递自定义消息正文,仅通过 custom_code 传验证码,自定义消息文本会返回错误 60243;按尝试发送计费(而非按完成验证计费),且自带验证码流程通常发送多于校验,成本高于标准 Verify;需手动将验证状态更新为 approved,以便 Twilio 的路由智能引擎持续优化投递。自带验证码应视为过渡手段而非最终状态。
错误处理映射:
- 号码格式错误/非 E.164、参数错误 → 60200,修正格式(用 Lookup)。
- 对某号码发送过多 → 60203,退避并提示稍后重试。
- 校验尝试过多 → 60202,发起新的验证。
- Service SID 错误 → 60212,检查 VERIFY_SERVICE_SID。
- 国家未启用 → 60410,在控制台启用地理权限。
- 传入了自定义消息 → 60243,仅用 custom_code,不要传正文。
速率限制与欺诈:Verify 默认对每个手机号每个 Service 执行 5 次发送/10 分钟和每次验证 5 次校验尝试。验证码存活 10 分钟且在该窗口内不可变(10 分钟内重新请求返回同一验证码)。这替代了手写的重发计数器。如需不同限制,可在 Service 上定义自定义 Rate Limits / Buckets。在控制台启用 Fraud Guard 可替代自建的短信泵送防护。
安全增量切换:
- 并行搭建 Verify,保留 Messaging 路径,将少量新 OTP 请求(或某地区/内部用户)路由到 Verify。
- 双跑校验:旧验证码走数据库校验,Verify 发出的走 verification_checks,需跟踪每个验证码由哪个系统签发。
- 排空后删除:当 10 分钟 TTL 内不再有旧验证码后,停止签发,将 Verify 提升到 100%,再下线 OTP 号码/Messaging Service 并删除 OTP 数据库表。
- 整个应用复用一个 Verify Service,不要每次请求都创建 Service。
适用场景
适用于标准 OTP/2FA 场景,希望减少自维护代码、获得内置限流与欺诈防护、并免除 OTP 号码的 10DLC 活动注册。若需要完全控制消息正文/品牌(超出模板允许范围)、自定义投递路由,或发送非 OTP 的事务性流量,则应继续使用 Programmable Messaging。
限制
- 无法取回 Verify 生成的验证码——任何 API 都不会返回(出于安全设计)。若旧流程会记录或显示验证码,该功能将失效。
- 默认无法将自有号码用作 Verify 发送方——Verify 按国家从托管号码池中选择(特定渠道/WhatsApp 可自带号码/Messaging Service,但非默认)。
- 无法传递原始自定义消息正文——customMessage 参数已弃用,原始文本会返回错误 60243。要自定义文案需使用已批准模板(TemplateSid)。
- custom_code 有附加条件:需按 Service 启用、按尝试计费(成本高于标准 Verify)、且必须手动更新验证状态。
- 无法自行更改 10 分钟令牌 TTL——默认值可在 2 分钟到 24 小时之间调整,但需联系 Twilio 支持在 Service 上设置。
- 无法重复校验已通过的验证——一次性,第二次校验返回 404。
- 无法向非 E.164 号码发送——需先规范化(Lookup)。
- 完成时无推送 webhook——需轮询 verification_checks(限流:60/分钟、180/小时、250/天)或使用 Verify Events API。
- 无法跳过 WhatsApp 发送方设置——自 2024 年 3 月 1 日起 Verify 无共享 WhatsApp 发送方,需自带。
- Verify 流量豁免 A2P,但该号码上其余非 OTP 的 Messaging 流量不豁免——仍需保留 10DLC 注册。