【问题标题】:password_verify is false on true passwordpassword_verify 在真密码上为假
【发布时间】:2019-12-17 13:51:11
【问题描述】:

我目前正在试验 password_hash() 和 password_verify() 方法..

所以我坚持我要继续创建一个小登录/注册。

问题是每当我打开登录时,输出是:

失败

我不知道为什么。我已经将数据库中密码字段的长度设置为 255,但它仍然不起作用。

这是我的 register.php

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

$username = mysqli_real_escape_string($db, $_GET['username']);
$password = mysqli_real_escape_string($db, $_GET['password']);

$p = password_hash($_GET['password'], PASSWORD_DEFAULT);

$stmt = $db->prepare("INSERT INTO users (username, password) VALUES (?,?)");
$stmt->bind_param('ss', $username, $p);

$stmt->execute();

$stmt->close();
$db->close();
?>

我的登录信息如下所示:

<?php
session_start();

error_reporting(0);

require_once('db.php');

function e($input) {
    return htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
}

$username = mysqli_real_escape_string($db, $_GET['username']);
$password = mysqli_real_escape_string($db, $_GET['password']);

$stmt = $db->prepare("SELECT username, password FROM users WHERE username = ?");
$stmt->bind_param('s', $username);

$stmt->execute();

$stmt->bind_result($username, $password);
$row = $stmt->fetch();

if (!empty($row)) { 
    if (password_verify($_GET['password'], $row['password'])) {
        echo 'success'; 
    } 
    else 
    {
        echo 'failed';
    }
} 
else 
{
    echo "This user does not exist"; 
}

$stmt->close();
$db->close();
?>

我不知道如何让它工作:/

【问题讨论】:

  • 在散列之前不必escape passwords 或对它们使用任何其他清理机制。这样做会更改密码并导致不必要的额外编码。
  • @JayBlanchard,我注意到了这一点,但后来注意到他们在比较中使用了$_GET['password']。他们还将bind_result() 用于这两个变量,然后使用来自$row 的值来自fetch()
  • 在调试代码时,您真的不应该使用error_reporting(0);,因为它会禁用所有警告、通知、错误等,从而使调试变得更加困难。
  • 实际上,正如刚刚向我指出的那样,您并没有在任何地方使用转义的密码和用户名。您可以消除所有这些代码。
  • 您需要养成accepting answers 的习惯,它可以帮助您解决问题。您将获得积分,并鼓励其他人帮助您。

标签: php mysqli prepared-statement password-hash


【解决方案1】:

$stmt-&gt;fetch(); 返回数据。它将数据绑定bind_result() 中定义的变量。

所以在$stmt-&gt;fetch() 之后,您将拥有$username 中的用户名和$password 中的密码。

那么,真正应该比较的是:

if ($stmt->fetch()) {
    // here 
    if (password_verify($_GET['password'], $password)) {
        echo 'success'; 
    } 
    else 
    {
        echo 'failed';
    }
} 
else 
{
    echo "This user does not exist"; 
}

【讨论】:

  • 啊……谢谢!我不知道 fetch 只是绑定数据而不返回它。它现在可以工作了!
  • @darby - 这是一个完美的例子,为什么在开发时关闭错误报告是不好的。这会引发关于尝试使用布尔值作为数组的通知,为您指明正确的方向。开发时最好有error_reporting(E_ALL)
猜你喜欢
  • 2020-08-02
  • 1970-01-01
  • 2017-11-02
  • 1970-01-01
  • 2017-07-06
  • 2022-10-20
  • 1970-01-01
  • 2016-05-22
  • 1970-01-01
相关资源
最近更新 更多