php - 如何在登录表单php上使用密码验证

标签 php mysql authentication mysqli passwords

我使用了一个登录表单,其中我对 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/

相关文章:

python - 在 Flask + SQLAlchemy 中设置一对一关系

javascript - 使用 sailsjs Passport 身份验证本地策略既不会给出任何错误,也不会对用户进行身份验证

jquery - JQuery 和 SharePoint Web 服务的身份验证问题

php - $_FILES 中的文件名不能很好地使用撇号

javascript - 根据设备的大小限制图像的下载

php - 带有可视化设计器的 PHP IDE?

security - 如何同时在 2 个不同的 symfony2 防火墙上进行身份验证?

php - 空选择字段表单值留下不需要的空白

php - SimpleXML 解析多个同名标签

php - 管理 CodeIgniter 中的 "A Database Error Occurred"1062 错误