PHP MySQL PDO OTP/2FA登录问题:错误OTP仍跳转home.php
问题排查:OTP验证不匹配仍跳转首页的问题
问题描述
我用PHP MySQL PDO实现了OTP/2FA登录功能,整体运行正常,但存在异常:在OTP输入框填写任意数字时,即便该数字与数据库中的OTP不匹配,页面仍会跳转到home.php。请帮忙排查代码中的问题或缺失项。
原代码
if(!empty($_POST["authenticate"]) && $_POST["otp"]!='') { try { $otp_code = $_POST["otp"]; $statement = $db->prepare("SELECT * FROM $table4 WHERE otp=:otp_code AND expired!=1 AND NOW() <= DATE_ADD(created, INTERVAL 10 MINUTE)"); $statement->bindParam(":otp_code", $otp_code); $statement->execute(); $count=$statement->rowCount(); if($count<1) { $data = [ 'expired' => 1, 'otp_code' => $otp_code, ]; $sql = "UPDATE $table4 SET expired=:expired WHERE otp=:otp_code"; $stmt= $db->prepare($sql); $stmt->execute($data); $_SESSION['otp_code'] = $otp_code; header("Location: home.php"); } else { $errorMessage = "Invalid Security Code!"; } } catch (PDOException $e) { echo "Error : Check your error message."; file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND); } } else if (!empty($_POST["otp"])) { $errorMessage = "Enter Security Code!"; }
问题核心
条件判断逻辑完全写反了:
- 当前代码中
if($count<1)的逻辑是「数据库中找不到匹配的有效OTP时」,执行跳转首页的操作 - 正确逻辑应该是「找到匹配的有效OTP时」才允许跳转,不匹配时提示错误
修复后的代码
if(!empty($_POST["authenticate"]) && $_POST["otp"]!='') { try { $otp_code = $_POST["otp"]; $statement = $db->prepare("SELECT * FROM $table4 WHERE otp=:otp_code AND expired!=1 AND NOW() <= DATE_ADD(created, INTERVAL 10 MINUTE)"); $statement->bindParam(":otp_code", $otp_code); $statement->execute(); $count=$statement->rowCount(); // 修正条件:找到匹配的有效OTP才执行登录逻辑 if($count>0) { // 标记该OTP为已过期,防止重复使用 $data = [ 'expired' => 1, 'otp_code' => $otp_code, ]; $sql = "UPDATE $table4 SET expired=:expired WHERE otp=:otp_code"; $stmt= $db->prepare($sql); $stmt->execute($data); $_SESSION['otp_code'] = $otp_code; header("Location: home.php"); // 跳转后必须终止脚本执行,避免后续代码运行 exit; } else { $errorMessage = "Invalid Security Code!"; } } catch (PDOException $e) { echo "Error : Check your error message."; file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND); } } else if (!empty($_POST["otp"])) { $errorMessage = "Enter Security Code!"; }
额外优化建议
- 跳转后添加
exit;,防止脚本继续执行引发不必要的问题 - 确保脚本最顶部已调用
session_start(),保证SESSION正常工作 - 如果OTP表关联了用户ID,建议在UPDATE语句中加入用户ID条件,避免同一OTP被不同用户使用时误标记过期
内容的提问来源于stack exchange,提问作者edokko
相关产品推荐
相关产品推荐

