0) { $err = '验证失败次数过多,已锁定,请 ' . $lock . ' 秒后再试'; secLog('2fa_throttled', 'lock=' . $lock . 's'); } else { $code = isset($_POST['code']) ? (string)$_POST['code'] : ''; if (secTotpVerify(SEC_2FA_SECRET, $code)) { $_SESSION['admin_2fa_ok'] = time(); $_SESSION['admin_2fa_ip'] = secClientIp(); secThrottleReset('twofa_fail', $sid); secLog('2fa_pass', 'session granted'); header('Location: ' . secTokenUrl('admin.php')); exit; } $left = secThrottleFail('twofa_fail', $sid, 5, 900); // ★ 诊断:把"密钥录错/绑了旧密钥"和"设备时钟漂移"两种失败原因区分开, // 否则用户只能看到一句"无效",无从下手。 $off = secTotpDiagnose(SEC_2FA_SECRET, $code); secLog('2fa_fail', $left > 0 ? 'LOCKED_' . $left . 's' : ($off === null ? 'wrong_secret' : 'clock_skew ' . $off . 's')); $err = $left > 0 ? '验证失败次数过多,已锁定,请 ' . $left . ' 秒后再试' : secTotpDiagnoseMsg($off); } } ?>