一、为什么验证码必须设置有效期?
验证码属于短期身份凭证。有效期过长会增加泄露、转发或被攻击者利用的时间窗口;有效期过短则可能在短信延迟、用户切换应用或网络较慢时提前失效。
有效期必须由服务端判断,不能只依赖前端倒计时。即使用户修改手机时间或绕过页面限制,服务端也应拒绝过期验证码。
二、如何确定合理有效期?
| 考虑因素 | 影响 |
|---|---|
| 操作风险 | 支付、改密等高风险操作通常需要更严格限制 |
| 实际送达延迟 | 应观察目标国家和运营商的p95延迟 |
| 用户操作复杂度 | 需要切换设备或填写更多信息时可能需要更长时间 |
| 备用验证方式 | 具备其他验证渠道时可采用更严格策略 |
| 攻击和欺诈风险 | 高风险用户可缩短有效期或增加额外验证 |
许多普通登录和注册流程会采用数分钟有效期,但具体数值应通过风险评估和真实用户数据确定,而不是机械复制其他网站。
三、验证码完整生命周期
生成使用安全随机数生成验证码。
存储保存哈希、用途、用户和过期时间。
发送通过高优先级OTP通道发送。
验证检查用户、用途、次数、时间和验证码。
失效验证成功、重发或过期后立即不可用。
四、重新发送时旧验证码怎么办?
系统必须明确采用“旧验证码立即失效”还是“短时间内保持同一验证码”的策略。无论哪种方式,都不能让多个验证码长期同时有效。
用户界面应明确提示最新验证码的生效规则。若每次重发都生成新码,旧短信延迟到达时容易造成用户输入错误,因此需要在模板或页面中引导用户使用最新消息。
五、错误次数和频率限制
- 限制单验证码允许的错误次数。
- 限制单号码和单用户的请求频率。
- 同时限制IP、设备和账户维度。
- 达到阈值后增加等待时间或额外验证。
- 不要通过错误提示泄露账户是否存在。
- 记录异常国家、号码和设备行为。
六、验证码存储与验证安全
验证码不应以明文长期保存。服务端可以保存带盐哈希、用户标识、业务用途、生成时间、过期时间和使用状态。
{
"user_id": "user_001",
"purpose": "login",
"otp_hash": "server-side-hash",
"expires_at": "2026-07-16T08:10:00Z",
"attempts": 0,
"used": false
}
验证时还应检查验证码是否属于当前用户和当前业务用途,避免注册验证码被用于修改密码。
七、延迟和用户体验
前端倒计时应与服务端有效期一致,并预留实际短信送达时间。不要在短信仍可能正常到达时立即允许连续重发。
- 显示清楚的剩余时间和重发等待时间。
- 对手机号进行掩码确认,帮助用户发现输入错误。
- 再次发送后说明旧验证码是否失效。
- 验证码过期后生成新流程,不继续重试旧短信。
- 持续分析送达延迟和验证成功率。