无法使用准备好的语句从数据库中提取密码哈希

Posted

技术标签:

【中文标题】无法使用准备好的语句从数据库中提取密码哈希【英文标题】:Unable to extract password hash from database with prepared statements 【发布时间】:2018-10-07 12:18:15 【问题描述】:

编辑:澄清一下,我无法使用准备好的语句从我的数据库中提取散列密码。

我正在尝试创建一个使用准备好的语句、password_hash 和 password_verify 的登录系统。

我创建了用于创建用户的注册表单,并使用 password_hash($_POST['password'], PASSWORD_DEFAULT); 散列密码

这可以正常工作。

但是,我现在被困在创建登录表单上。

我正在尝试获取用户注册时存储的密码哈希,但我无法让它与准备好的语句一起使用。

这是我目前拥有的。

<?php
require('db.php');

if(isset($_POST['submit'])) 
  $stmt = $connect->prepare('SELECT user_name, user_password FROM `users` WHERE user_name = ?');

  if($stmt) 
    $username = $_POST['username'];
    $password = $_POST['password'];

    $stmt->bind_param('s', $username);

    $stmt->execute();

  


?>

如何使用从选择查询中获得的数据?以及如何使用它来验证密码?

我试过了:

$stmt->store_result();
$stmt->bind_result($loginUsername, $hash);

那只存储了用户名,而不是密码哈希,我不知道为什么。

验证密码会使用这个吗? password_verify($password, $hash);

更新

<?php
require('db.php');

if(isset($_POST['submit'])) 
  $stmt = $connect->prepare('SELECT user_name, user_password FROM `users` WHERE user_name = ?');

  if($stmt) 
    $username = $_POST['username'];
    $password = $_POST['password'];

    $stmt->bind_param('s', $username);

    $stmt->execute();

    // Get query results
    $result = $stmt->get_result();

    // Fetch the query results in a row
    while($row = $result->fetch_assoc()) 
      $hash = $row['user_password'];
      $username = $row['user_name'];
    

    // Verify user's password $password being input and $hash being the stored hash
    if(password_verify($password, $hash)) 
      // Password is correct
     else 
      // Password is incorrect
    

  


?>

【问题讨论】:

那么您的实际问题是为什么您的查询不起作用并且与password_verify() 完全无关? @Sammitch 这是主要问题,正确。我以前也很少使用这些功能,所以我不确定我是否正确使用它们。 你会做某种fetch() 来实际获取任何地方的结果行 @RiggsFolly 我需要使用类似于$row = $result-&gt;fetch_assoc()的东西吗 如果一切都失败了,您可以阅读手册,从 bind_result() 页面开始,那里有一个有用的示例 【参考方案1】:

阅读这个PHP MANUAL。试试这个:

 <?php
    require('db.php');

    if(isset($_POST['submit'])) 
      $stmt = $connect->prepare('SELECT user_name, user_password FROM `users` WHERE user_name = ?');

      if($stmt) 
        $username = $_POST['username'];
        $password = $_POST['password'];

        $stmt->bind_param('s', $username);

        $stmt->execute();

        // Get query results
        $stmt->bind_result($user_name,$hash);
        $stmt->store_result();

        // Fetch the query results in a row
        $stmt->fetch();

        // Verify user's password $password being input and $hash being the stored hash
        if(password_verify($password, $hash)) 
          // Password is correct
         else 
          // Password is incorrect
        

      
    

    ?>

这就是我创建登录系统的方式:

$stmt = mysqli_prepare($link,"SELECT user_email,user_password,user_firstname,user_lastname,user_role,username FROM users WHERE user_email=?");
        mysqli_stmt_bind_param($stmt,"s",$email);
        mysqli_stmt_execute($stmt);
        confirmQuery($stmt);
        mysqli_stmt_bind_result($stmt,$user_email,$user_password,$user_firstname,$user_lastname,$user_role,$username);
        mysqli_stmt_store_result($stmt);
        mysqli_stmt_fetch($stmt);
        if(mysqli_stmt_num_rows($stmt) == 0)
            relocate("../index.php?auth_error=l1");
        else
            if(password_verify($password,$user_password))
                $_SESSION['userid'] = $user_email;
                $_SESSION['username'] = $username;
                $_SESSION['firstname'] = $user_firstname;
                $_SESSION['lastname'] = $user_lastname;
                $_SESSION['role'] = $user_role;
                if(isset($_POST['stay-logged-in']))
                    setcookie("userid", $email, time() + (86400 * 30), "/");
                relocate("../index.php?auth_success=1");
            else
                relocate("../index.php?auth_error=l2");
        
        mysqli_stmt_close($stmt);

【讨论】:

以上是关于无法使用准备好的语句从数据库中提取密码哈希的主要内容,如果未能解决你的问题,请参考以下文章

PHP:准备好的语句无法从单引号中逃脱

无法在准备好的 INSERT 语句中的 python mysql.connector 中使用 None (NULL) 值

如何使用arraylist作为准备好的语句参数[重复]

如果在循环中使用 MySQLi 准备好的语句,我啥时候调用 bind_param?

mysql性能中的PDO

无法使用 Morphia 从 Mongo db 中提取 - 没有可用的构造函数