说明:本次草稿依据提交记录,未逐行核对实现。提交未给出阿里云 API 的具体参数与细节;查不到的只讲思路,不编造阿里云 API 的具体参数名。

背景:短信是入口,也是最易被滥用的入口

在本项目,手机号验证码是统一登录入口的一部分。README 记载,真实 Provider 需配置腾讯云 SMS 后才会显示——短信不是默认就有的能力,而是依赖 Provider 配置的能力。

短信看起来简单,实则处处是风险:花钱、可能被刷、模板要合规、失败要可控。一次提交(2026-10-07)与一次提交(2026-10-07)讲的,就是如何把短信从“调一个接口发一条短信”变成一套可管理、可兜底、可限流的服务。

为什么要做 Provider 选择器,而不是写死一家

其中一次提交提到 Provider 选择器,默认保留腾讯;另一条提到核心适配器:阿里云 PNVS 客户端 + 腾讯兜底。设计是“可选择、可切换”,而非写死某一家。

首先是可用性:任何一家都可能故障,写死一家,故障时验证码登录会整体停摆;有选择器与兜底,主 Provider 失败时可切备用,用户几乎无感知。其次是成本与合规:不同 Provider 的价格、到达率、合规要求可能不同,选择器让决策在配置层做,而非每次改代码。最后是演进:Provider 可能增减替换,到处直接调某家 SDK,换一家就要改多处;选择器 + 适配器把“用哪家”与“怎么发”分开。

模板按用途区分:登录、绑定、二次验证不是同一条短信

提交提到“按用途区分模板:登录、绑定、二次验证”。不同用途语义完全不同:登录是“证明你是这个手机号的主人”,绑定是“把号码绑到当前账号”,二次验证是“敏感操作前再确认一次身份”。共用同一模板,用户收到时无法分辨对应哪件事;一旦短信被误用或诱导转发,风险也会放大。

按用途区分有三个好处:用户能看懂短信是干什么的,减少误操作;服务端可按用途做不同的校验与有效期策略;出问题时可按用途定位,而非所有验证码混在一起查。

还提到“用途透传”:用途要贯穿整个验证链路,发送时选对模板,校验时也要确认用途一致,登录的验证码不能被拿去完成绑定,反之亦然。

门控与每日上限:失败发送也要计数

提交提到“大陆手机号门控”:发送前先判断号码是否符合条件,不符合直接拒绝,不走到 Provider 调用。具体规则提交未给出,本文不编。门控的意义是避免把明显不符合条件的请求发到 Provider,既省钱,也减少无效调用与合规风险。门控解决“能不能发”,限流解决“能发多少次”。

提交还提到“可配置全局每日发送上限,失败发送也计数”。上限可配置,阈值可随运营情况调整。失败也计数则更关键:直觉上“只有成功才算一次”是错的。攻击者刷接口时,大量请求可能因号码无效、Provider 拒绝、网络超时而失败;若失败不计数,攻击者可用失败请求无限消耗资源,而限流永远触发不了。把失败也算进去,才能真正限制“尝试次数”,而非只限制“成功次数”。## 错误净化与双层限流

提交提到“净化 Provider 错误,永不泄露 SDK 原文”。SDK 出错时可能返回含内部信息的原文:接口地址、账号信息、内部错误码、调用细节。若直接返回给客户端,等于把内部实现暴露给外部,攻击者可据此推断用的是哪家 Provider、配置是什么、哪里出了问题。净化的做法是:服务端收到错误后,只向客户端返回通用的安全描述;详细原始错误只记在服务端日志里,供内部排查。“永不泄露”措辞绝对,说明它不是建议,而是底线。

存储文档记载,带限流的短信、登录、上传等接口先后计入 Redis 和 PG,PG 预留顺序为权威。结合每日上限,可理解为双层限流:Redis 负责快速计数,短信发送是高频操作,每次都要判断“今天已发多少次”,Redis 读写快,适合做高频判断;PG 负责持久与权威,Redis 可能失效、重启、丢数据,PG 里的预留记录则是持久的、可作为最终依据的。

分工是:Redis 是加速层,PG 是正确性权威。Redis 失效不应放开限制,PG 的持久计数与预留才是最终依据。本文未逐行核对实现,不写具体顺序与代码。

踩坑

第一,短信不要写死一家,选择器 + 适配器 + 兜底是可用性与演进能力的基础。第二,模板要按用途区分,用途要一路透传,登录、绑定、二次验证的验证码不能混用。第三,门控要在发送前做,先判断能不能发,再调 Provider。第四,失败发送也要计入上限,限流限制的是尝试次数,不是成功次数。第五,错误信息要净化,SDK 原文只留在服务端日志里。第六,Redis 只是加速层,PG 才是权威,Redis 失效可以变慢,但不能变错。

小结:短信验证码的难点不在“发一条短信”,而在“发得可控、可兜底、可追溯”。选择器解决可用性,模板区分解决语义,门控与每日上限解决滥用,错误净化解决信息泄露,Redis + PG 的双层设计则解决“快”与“对”之间的平衡。


2024 | ixs.im
此情此景, [随机]吟诗一首: