同一个人连续提交两次,第一次输错后点了刷新,用旧图上的四个字符第二次居然通过了。日志里两条校验记录间隔 40 秒。碰到这种情况,我一般先确认改动有没有真的生效。

原因不复杂,刷新只换了页面上的图片,服务端把新码覆盖进 session,却留着上一次的码继续可比。校验逻辑遍历了历史码,命中一个就放行。

「验证码刷新失效」这类改动最怕改一半,回滚脚本先准备好,再动生产。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。

session_start();
$code = random_int(1000, 9999);
$_SESSION['captcha'] = ['code' => $code, 'at' => time()];
// 校验后
unset($_SESSION['captcha']);

权限不要一口气开到最大,先加到够用再往上试,范围小才好收。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。

具体做法是,刷新时生成新码并直接覆盖旧值,不保留上一条;校验通过或失败都立即销毁当前码,做到一次有效;给验证码加签发时间,超过两分钟按过期处理。

最后用这个标准收尾,刷新后再用旧码提交返回验证码错误,新码只能通过一次,第二次即失效。

作者 9823189