验证码的有效期与重试设计:几秒过期、几次重发、怎么防枚举
先把三个参数分开看,它们的取舍方向不同:
| 参数 | 偏向安全 | 偏向体验 |
|---|---|---|
| 有效期 | 短(60s) | 长(10min) |
| 重发间隔 | 长(120s) | 短(30s) |
| 错误次数上限 | 少(3 次) | 多(10 次) |
一、有效期:3–5 分钟是合理区间
太短(60 秒)的问题是运营商延迟——短信从提交到送达经常要 5–30 秒,弱网或跨网时更久。60 秒的有效期意味着用户收到时可能只剩 30 秒。
太长(30 分钟)的问题是被枚举的概率上升,且旧验证码容易在别的场景被复用。
实用值:5 分钟,并在短信正文里写明。
二、重发:间隔 60s,总量 5 次
两个维度都要限:
单次间隔:60 秒(前端倒计时)
单日总量:同一号码 5–10 次
前端倒计时只是体验,后端必须再校验一次——前端可以绕过。
三、防枚举:三次错误即失效
验证码通常是 6 位,理论上有 100 万种组合。如果不限次数,脚本几分钟就能撞开。
正确做法:
- 同一验证码错误 3 次立即失效,强制重新获取;
- 同一号码错误 10 次,锁定 1 小时;
- 错误响应不要泄露信息:「验证码错误」可以,「验证码错误,还剩 2 次」等于告诉攻击者进度。
四、验证码存哪、怎么存
- 存服务端:Redis 带 TTL 最合适,键用「场景 + 手机号」;
- 不要存明文:库里存哈希值,避免数据泄露时验证码被直接使用;
- 一次性:验证成功后立刻删除,别留着「5 分钟内可重复用」;
- 绑定场景:注册、登录、改密码的验证码不能互相通用。
五、几个容易被忽略的设计
1. 同一号码多场景互不影响
用户同时在做「注册」和「找回密码」时,两个验证码应该是独立的键,否则后发的会覆盖先发的。
2. 换号重试要清空旧状态
用户输错号码再改,旧的限流计数应该清掉,否则新号码一上来就被限。
3. 图形验证与短信验证分开计时
图形验证的失败次数不应该计入短信的限流——它们是两道不同的门。
六、验证成功之后的安全动作
- 签发短时效 token:不要直接把手机号当已认证标识传下去;
- 绑定设备:同一手机号换设备登录时二次验证;
- 记录日志:手机号、时间、IP、UA,出事能追。
数据合规的要求见 数据合规落地:中小站点到底要做什么;防刷策略见 短信验证码防刷。
七、一张参数速查表
有效期 5 分钟
重发间隔 60 秒
单日上限 5–10 次
错误上限 3 次(单码)/ 10 次(单号)
存储 Redis + TTL + 哈希
成功即删 是
场景隔离 是
相关阅读
版权声明:如无特殊标注,文章均为本站原创,转载时请以链接形式注明文章出处。







评论