登录页错误提示异常及邮箱验证码登录改造技术求助
登录功能问题修复与邮箱验证码改造方案
一、修复登录失败提示问题
原代码的核心问题是:当用户名不存在时,查询结果为空,while循环不会执行,导致无法触发登录失败弹窗。以下是修复后的完整代码及说明:
修复后的PHP代码(含后续验证码功能)
<!DOCTYPE html> <html lang="en"> <body> <?php session_start(); // 开启session用于存储验证码 $servername = "localhost"; $username = "root"; $password = ""; $database = "my_db"; mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); $conn = mysqli_connect($servername, $username, $password, $database); mysqli_set_charset($conn, 'utf8mb4'); // 处理登录请求 if(isset($_POST['login_Btn'])){ $username = $_POST['username']; $password = $_POST['password']; $captcha = $_POST['captcha']; // 先验证验证码 if(empty($_SESSION['email_captcha']) || strtolower($captcha) != strtolower($_SESSION['email_captcha']) || time() > $_SESSION['captcha_expire']){ echo "<script>alert('验证码错误或已过期');</script>"; exit; } // 预处理查询,防止SQL注入 $sql = "SELECT * FROM logindetails WHERE username = ?"; $stmt = mysqli_prepare($conn, $sql); mysqli_stmt_bind_param($stmt, "s", $username); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if(mysqli_num_rows($result) === 0){ // 用户名不存在 echo "<script>alert('登录失败:用户名或密码错误');</script>"; } else { $row = mysqli_fetch_assoc($result); // 生产环境务必用password_verify替代明文对比 if(password_verify($password, $row['password'])) { unset($_SESSION['email_captcha']); // 销毁验证码 header('Location:index.html'); exit; } else { echo "<script>alert('登录失败:用户名或密码错误');</script>"; } } } // 处理发送验证码请求 if(isset($_POST['send_captcha'])){ $username = $_POST['username']; $sql = "SELECT email FROM logindetails WHERE username = ?"; $stmt = mysqli_prepare($conn, $sql); mysqli_stmt_bind_param($stmt, "s", $username); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if(mysqli_num_rows($result) === 0){ echo "<script>alert('用户名不存在');</script>"; exit; } $row = mysqli_fetch_assoc($result); $user_email = $row['email']; $captcha = rand(100000, 999999); // 生成6位验证码 $_SESSION['email_captcha'] = $captcha; $_SESSION['captcha_expire'] = time() + 300; // 5分钟有效期 // 发送邮件(生产环境建议用PHPMailer替代原生mail) $subject = "登录验证码"; $message = "您的登录验证码是:$captcha,5分钟内有效。"; $headers = "From: your-service@example.com"; // 替换为你的发件邮箱 if(mail($user_email, $subject, $message, $headers)){ echo "<script>alert('验证码已发送至您的邮箱');</script>"; } else { echo "<script>alert('验证码发送失败,请稍后重试');</script>"; } } ?> </body> </html>
修复关键点
- 用
mysqli_num_rows()判断查询结果是否存在用户记录,覆盖用户名不存在的场景 - 统一错误提示为“用户名或密码错误”,避免泄露用户存在性信息(安全优化)
- 改用预处理语句执行SQL,彻底解决原代码的SQL注入风险
- 新增密码验证的安全提示:生产环境必须使用
password_hash()加密存储密码,用password_verify()验证
二、邮箱验证码功能改造
修改后的HTML登录页
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login Page</title> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f0f0f0; } .container { width: 300px; padding: 20px; background-color: #fff; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } h2 { text-align: center; } input[type="text"], input[type="password"] { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } .captcha-group { display: flex; gap: 10px; margin: 10px 0; } .captcha-group input { flex: 1; } .send-captcha-btn { padding: 10px 12px; border: none; border-radius: 4px; background-color: #28a745; color: #fff; cursor: pointer; white-space: nowrap; } .send-captcha-btn:hover { background-color: #218838; } input[type="submit"] { width: 100%; padding: 10px; border: none; border-radius: 4px; background-color: #007bff; color: #fff; cursor: pointer; } input[type="submit"]:hover { background-color: #0056b3; } </style> </head> <body> <div class="container"> <h2>Login</h2> <form action="login.php" method="post"> <input type="text" name="username" placeholder="Username" required> <input type="password" name="password" placeholder="Password" required> <div class="captcha-group"> <input type="text" name="captcha" placeholder="验证码" required> <button type="button" class="send-captcha-btn" onclick="sendCaptcha()">发送验证码</button> </div> <input type="submit" value="Login" class="loginBtn" name="login_Btn"> </form> </div> <script> function sendCaptcha() { const username = document.querySelector('input[name="username"]').value; if(!username.trim()) { alert('请先输入用户名'); return; } // AJAX发送请求,避免页面刷新 const xhr = new XMLHttpRequest(); xhr.open('POST', 'login.php', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('send_captcha=1&username=' + encodeURIComponent(username)); } </script> </body> </html>
功能实现说明
前端部分
- 添加验证码输入框和“发送验证码”按钮,用Flex布局优化排版
- 编写AJAX函数
sendCaptcha(),在不刷新页面的情况下请求发送验证码 - 增加用户名输入校验,避免空请求
后端部分
- 开启
session存储验证码及其5分钟有效期 - 新增
send_captcha请求处理逻辑:根据用户名查询用户邮箱,生成随机验证码并发送 - 登录流程中优先验证验证码的有效性(是否匹配、是否过期)
- 登录成功后销毁验证码session,防止重复使用
生产环境注意事项
- 原生
mail()函数依赖服务器邮件配置,建议使用PHPMailer、SwiftMailer等专业邮件库提升稳定性 - 必须对用户密码进行哈希加密存储,禁止明文存储
- 可添加验证码发送频率限制,防止恶意请求
内容的提问来源于stack exchange,提问作者Methodius5510
相关产品推荐
相关产品推荐

