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

Posted

技术标签:

【中文标题】如何在登录表单php上使用密码验证【英文标题】:How to use password verify on the login form php 【发布时间】:2019-11-24 20:32:58 【问题描述】:

我使用了一个对 SQL 注入开放的登录表单,我正在尝试使用准备好的语句来修复它。我不知道代码有什么问题。我以前从未使用过带有准备好的语句的登录表单。

这是我一开始尝试的。

$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();

我在最后一个代码中得到的错误消息是“绑定变量的数量与准备好的语句中的字段数量不匹配”。

【问题讨论】:

您只需要选择您绑定的列,不多也不少。所以SELECT password 或任何被称为列的列 摆脱这个丑陋的 bind_result() 方法,取而代之的是一个熟悉的 assoc 数组。这是example 【参考方案1】:

您不能在WHERE 子句中使用密码(因此您的第二种方法是正确的),因为每次使用它时哈希值都会有所不同。此外,您应该始终选择所需的特定列数,因为您需要使用bind_result() 定义每一列。它可以与SELECT * 一起使用,但是你依赖bind_result() 来覆盖所有可能的值——如果你突然向表中添加另一列,这将会中断。

$stmt = $db->prepare("SELECT password FROM users WHERE username = ?");
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$stmt->bind_result($hash);

if ($stmt->fetch() && password_verify($_POST['password'], $hash)) 
    $_SESSION['username'] = $username;
    header('location: indexclient.php');
    exit;
 else 
  echo "Invalid login";

$stmt->close();

【讨论】:

以上是关于如何在登录表单php上使用密码验证的主要内容,如果未能解决你的问题,请参考以下文章

php form提交账户密码 怎么写验证

使用 php 和 ajax 进行登录表单验证

Spring Security Ldap验证userDn和登录表单中的密码

php header头如何添加Authorization登录验证?

Laravel 验证登录表单验证在密码确认中失败?

使用 ASP.NET 表单身份验证,如何让图像出现在登录屏幕上?