我使用了一个登录表单,其中我对 SQL 注入(inject)持开放态度,并且我正在尝试使用准备好的语句来修复它。我不知道代码有什么问题。我以前从未使用过带有准备好的语句的登录表单。
这是我一开始尝试的。
$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$stmt = mysqli_prepare($db, $query);
mysqli_stmt_bind_param($stmt, 'ss', $username, $password);
$stmt->execute();
$stmt->bind_result($username, $password);
$hash = $password;
if (password_verify($password,$hash)) {
$_SESSION['username'] = $username;
exit(header('location: indexclient.php'));
}
这就是我现在正在尝试的。
$stmt = $db->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$stmt->bind_result($hash);
$stmt->fetch();
if (password_verify($_POST['password'], $hash)) {
$_SESSION['username'] = $username;
exit(header('location: indexclient.php'));
} else {
echo "Invalid login";
}
$stmt->close();
我在最后一个代码中收到的错误消息是“绑定(bind)变量的数量与准备好的语句中的字段数量不匹配”。
最佳答案
您不能在 WHERE
子句中使用密码(因此您的第二种方法是正确的),因为每次使用时的哈希值都会不同。此外,您应该始终选择所需的具体列数,因为您需要使用 bind_result()
定义每一列。它可以与 SELECT *
一起使用,但随后您依赖 bind_result()
来覆盖所有可能的值 - 如果您突然向表中添加另一列,这将会中断。
$stmt = $db->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
if ($user && password_verify($_POST['password'], $user['password'])) {
$_SESSION['user_id'] = $user['id'];
header('location: indexclient.php');
exit;
} else {
echo "Invalid login";
}
$stmt->close();
关于php - 如何在登录表单php上使用密码验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57051602/