简单密码验证函数无法正常工作,请求排查代码问题
你的密码验证函数逻辑存在问题
这段代码的逻辑不正确,有几个关键错误需要修正:
- 错误使用
mysqli_fetch_field:这个函数的作用是获取结果集中的字段元数据(比如字段名称、数据类型),而不是获取查询到的用户密码数据。你应该用mysqli_fetch_assoc($result)或者mysqli_fetch_row($result)来提取用户的密码记录。 - 明文密码比较的风险:即使你正确获取到了密码,直接用
==比较明文密码是非常不安全的——正常情况下数据库应该存储的是通过password_hash()生成的哈希值,而非明文。正确的做法是用password_verify()函数来验证密码和哈希值是否匹配。 - 缺少错误检查:没有判断
mysqli_query()是否执行成功,如果查询失败(比如数据库连接问题),$result会是false,后续调用mysqli_fetch_field()会直接抛出错误。
修正后的示例代码
function password_matches($username, $password){ // 转义用户名防止SQL注入(不过更推荐使用预处理语句) $u = $GLOBALS['conn']->real_escape_string($username); $q = "SELECT password FROM users WHERE username = '$u'"; $result = mysqli_query($GLOBALS['conn'], $q); // 检查查询是否执行成功 if (!$result) { // 根据业务需求处理错误,比如返回false或抛出异常 return false; } // 获取用户的密码哈希记录 $user = mysqli_fetch_assoc($result); // 兜底检查:确保查询到了用户(即使你预设了user_exists) if (!$user) { return false; } // 使用PHP官方推荐的密码验证函数 return password_verify($password, $user['password']); }
额外安全建议
更稳妥的做法是使用预处理语句替代real_escape_string,可以彻底避免SQL注入风险,示例如下:
function password_matches($username, $password){ $stmt = $GLOBALS['conn']->prepare("SELECT password FROM users WHERE username = ?"); $stmt->bind_param("s", $username); $stmt->execute(); $result = $stmt->get_result(); $user = $result->fetch_assoc(); if (!$user) { return false; } return password_verify($password, $user['password']); }
内容的提问来源于stack exchange,提问作者Nicolás Reyes
相关产品推荐
相关产品推荐

