You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

双表单(注册/登录)下如何正确实现账号密码验证?

问题分析与解决方案

你的登录功能允许任意密码登录,核心问题有两个:

  • 登录逻辑和注册逻辑混合执行,无论登录还是注册请求,都会先跑一遍注册的查询和插入流程,导致不必要的数据库操作甚至错误。
  • 登录时未正确验证密码:你用当前请求生成的哈希密码去数据库查询,而非取出数据库中存储的对应用户的哈希密码,再验证输入密码是否匹配。

修正后的代码实现

// 注册逻辑单独处理
if (isset($_POST['reg_user'])) {
    $username = mysqli_real_escape_string($db, $_POST['name']);
    $email = mysqli_real_escape_string($db, $_POST['email']);
    $password = mysqli_real_escape_string($db, $_POST['password']);
    
    // 先检查用户是否已存在
    $query = "SELECT * FROM utilisateur WHERE pseudoUtil='$username' OR mailUtil='$email'";
    $results = mysqli_query($db, $query);
    if(mysqli_num_rows($results) == 1){
        $_SESSION['message'] = "用户已存在!"; 
    } else {
        // 生成哈希密码后插入数据库
        $hashed_password = password_hash($password, PASSWORD_DEFAULT);
        mysqli_query($db, "INSERT INTO utilisateur (pseudoUtil, mailUtil, pwdUtil) VALUES ('$username', '$email', '$hashed_password')");
        $_SESSION['message'] = "注册完成 :)"; 
    }
}

// 登录逻辑单独处理
if (isset($_POST['login_user'])) {
    $username = mysqli_real_escape_string($db, $_POST['name']);
    $email = mysqli_real_escape_string($db, $_POST['email']);
    $password = mysqli_real_escape_string($db, $_POST['password']);
    
    // 根据用户名/邮箱查询对应的用户数据(包含存储的哈希密码)
    $query = "SELECT * FROM utilisateur WHERE pseudoUtil='$username' OR mailUtil='$email'";
    $results = mysqli_query($db, $query);
    
    // 检查是否存在该用户
    if(mysqli_num_rows($results) == 1){
        $user = mysqli_fetch_assoc($results);
        // 用password_verify验证输入密码与数据库存储的哈希密码是否匹配
        if(password_verify($password, $user['pwdUtil'])){
            $_SESSION['username'] = $username;
            header('location: index.php'); 
            exit; // 跳转后终止脚本执行,避免后续代码运行
        } else {
            $_SESSION['message'] = "用户名/邮箱或密码错误!";
        }
    } else {
        $_SESSION['message'] = "用户名/邮箱或密码错误!";
    }
}

关键修正点说明

  • 拆分逻辑:将注册和登录代码分开处理,避免互相干扰。
  • 正确的密码验证流程:
    1. 根据用户名/邮箱从数据库取出用户完整数据(包括注册时存储的pwdUtil哈希密码字段)。
    2. 使用PHP内置的password_verify()函数,自动处理哈希盐值等细节,验证输入明文密码与数据库哈希密码是否匹配。
  • 添加错误提示:登录失败时返回明确提示,提升用户体验。
  • 跳转后终止脚本:用exit确保跳转后脚本不再执行,避免潜在问题。

额外安全建议

建议使用预处理语句替代mysqli_real_escape_string,更彻底地防范SQL注入攻击,示例如下:

注册的预处理语句示例

if (isset($_POST['reg_user'])) {
    $username = $_POST['name'];
    $email = $_POST['email'];
    $password = $_POST['password'];
    
    // 预处理查询检查用户是否存在
    $stmt = mysqli_prepare($db, "SELECT * FROM utilisateur WHERE pseudoUtil=? OR mailUtil=?");
    mysqli_stmt_bind_param($stmt, "ss", $username, $email);
    mysqli_stmt_execute($stmt);
    $results = mysqli_stmt_get_result($stmt);
    
    if(mysqli_num_rows($results) == 1){
        $_SESSION['message'] = "用户已存在!"; 
    } else {
        $hashed_password = password_hash($password, PASSWORD_DEFAULT);
        // 预处理插入语句
        $stmt = mysqli_prepare($db, "INSERT INTO utilisateur (pseudoUtil, mailUtil, pwdUtil) VALUES (?, ?, ?)");
        mysqli_stmt_bind_param($stmt, "sss", $username, $email, $hashed_password);
        mysqli_stmt_execute($stmt);
        $_SESSION['message'] = "注册完成 :)"; 
    }
}

登录的预处理语句示例

if (isset($_POST['login_user'])) {
    $username = $_POST['name'];
    $email = $_POST['email'];
    $password = $_POST['password'];
    
    $stmt = mysqli_prepare($db, "SELECT * FROM utilisateur WHERE pseudoUtil=? OR mailUtil=?");
    mysqli_stmt_bind_param($stmt, "ss", $username, $email);
    mysqli_stmt_execute($stmt);
    $results = mysqli_stmt_get_result($stmt);
    
    if(mysqli_num_rows($results) == 1){
        $user = mysqli_fetch_assoc($results);
        if(password_verify($password, $user['pwdUtil'])){
            $_SESSION['username'] = $username;
            header('location: index.php'); 
            exit;
        } else {
            $_SESSION['message'] = "用户名/邮箱或密码错误!";
        }
    } else {
        $_SESSION['message'] = "用户名/邮箱或密码错误!";
    }
}

内容的提问来源于stack exchange,提问作者YapYap31

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 06:27:37