手机Authenticator刚生成的验证码也被拒绝,换管理员账号仍一样。TOTP按30秒时间窗计算,多节点时间漂移或时区/UTC配置混乱时,会出现“偶尔能进、偶尔全错”。

先说结论

先用一个真实失败样本复现,不要一上来全量重建。把请求、实体ID和时间记下来,后面的SQL与日志才能对得上。

定位过程

  • 分别在所有Web节点执行UTC时间查询,与可信NTP源比较。
  • 确认失败请求实际落到哪台节点。
date -u +"%Y-%m-%dT%H:%M:%SZ"
timedatectl status
chronyc tracking || ntpq -pn
for h in web1 web2; do ssh "$h" date -u +%s; done

日志取样要带上请求时间、Store View、实体ID和部署版本。只截一行异常往往不够,至少保留错误前后几十行,才能判断是入口参数还是后续状态被改写。

可执行方案

启用chrony或systemd-timesyncd,让所有节点同步到同一可信NTP源;先slew校时,生产高峰避免大幅step影响任务。统一硬件时钟与系统UTC,PHP显示时区不影响TOTP基准。同步后重新验证现有2FA密钥,不必先关闭2FA。

实施时的顺序

  • 先做数据与配置备份,记录当前值。
  • 只改一个变量并重跑失败样本。
  • 确认新数据正确后,再处理历史受影响记录。
  • 最后恢复定时任务或缓存。

上线后观察什么

  • 所有节点Unix时间差在允许范围内
  • 连续两个TOTP时间窗均可登录
  • 负载均衡切换节点仍成功
  • NTP偏移有监控告警

验收不只看后台提示“成功”。我还会从前台/API再走一次真实链路,并在下一轮cron、索引或缓存命中后重复检查,确认不是短暂正常。

风险点

不要因为时间问题直接全局禁用2FA,先修基础时钟。