PHP中password_verify从数据库取哈希时始终返回false问题
问题
开发登录页面时遇到以下问题:使用从数据库获取的哈希值调用password_verify()始终返回false,但使用静态哈希值时验证正常通过。相关代码如下:
<?php require_once "ID.php"; $message = ""; if ($_SERVER["REQUEST_METHOD"] === "POST") { // Connect to the database $conn = new mysqli($DB_SERVER, $DB_USER, $DB_PASSWORD, $DB_NAME); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $pseudo = $_POST['pseudo']; $passwordInput = trim($_POST['password']); // Fetch the stored password hash $stmt = $conn->prepare("SELECT password FROM users WHERE Pseudo = ?"); $stmt->bind_param("s", $pseudo); $stmt->execute(); $stmt->bind_result($storedHash); $stmt->fetch(); // Debugging: Output the fetched stored hash and length echo "Stored Hash: $storedHash<br>"; echo "Stored Hash Length: " . strlen($storedHash) . "<br>"; // Check if we found the user if ($storedHash) { // Debugging: Check if password verification passes $verifyResult = password_verify($passwordInput, $storedHash) ? "true" : "false"; echo "Password verify result: $verifyResult<br>"; if (password_verify($passwordInput, $storedHash)) { $message = "Login successful!"; } else { $message = "Invalid username or password."; } } else { $message = "User not found."; } $stmt->close(); $conn->close(); } ?> <!DOCTYPE html> <html> <head> <title>Login</title> </head> <body> <h2>Login</h2> <?php if ($message) echo "<p>$message</p>"; ?> <form method="POST" action=""> <input type="text" name="pseudo" placeholder="Username" required><br> <input type="password" name="password" placeholder="Password" required><br> <button type="submit">Login</button> </form> </body> </html>
解决方案
- 检查数据库字段长度:
password_hash()生成的哈希值默认长度为60字符,必须确保数据库中password字段的类型为VARCHAR(255)(禁止使用长度不足的VARCHAR(50)或TEXT,前者会截断哈希值,后者可能引入隐形字符)。 - 清除哈希值的隐形字符:从数据库取出哈希值后,先执行
trim()处理,避免存在空格、换行符等隐形字符导致验证失败:$storedHash = trim($storedHash); - 核对存储的哈希值完整性:手动对比数据库中存储的哈希值与
password_hash()生成的原始哈希值,确认两者完全一致,排除存储时的编码转换或截断问题。 - 统一字符编码:确保数据库连接、数据表及字段的字符编码为
utf8mb4,避免哈希值存储时出现字符损坏。 - 完善fetch逻辑:
$stmt->fetch()可能未正确获取数据,建议添加判断逻辑:if (!$stmt->fetch()) { $message = "User not found."; $stmt->close(); $conn->close(); // 终止后续验证逻辑,直接输出结果 }
内容的提问来源于stack exchange,提问作者Max Lhrm
相关产品推荐
相关产品推荐

