【问题标题】:password_verify fails in an if statementpassword_verify 在 if 语句中失败
【发布时间】:2018-11-06 10:48:54
【问题描述】:

编辑:我猜星星只是失去了对齐,因为在重新加载页面并尝试再次使用它之后它可以工作。


我正在使用用户帐户创建一个简单的管理系统。我很难使用登录位,因为由于某种原因password_verify 在 if 语句中会失败。这可能与我从数据库中获取密码的方法有关,但我不确定。

这就是不工作的地方

$query = $db->query("SELECT * FROM users WHERE `username` = '" . $db->real_escape_string($_POST['username']) . "';");

if (!$query or $query == NULL)
{
    echo $db->error . "<br>";
    exit("EXIT: database error");
}

while ($row = $query->fetch_assoc())
{
    if (password_verify($_POST['password'], $row['password']))
    {   
        $db->close();
        header("LOCATION: main.php");
        exit;
    }
    else
    {
        header("LOCATION: index.php?error=Wrong password.");
        exit("wrong password<br>");
    }
}

如果我将if (password_verify($_POST['password'], $row['password'])) 替换为

$success = password_verify($_POST['password'], $row['password']);
if ($success)
// success

它按预期工作。我做($row = $query-&gt;fetch_assoc()) 有什么问题吗,还是我在其他地方犯了错误?我不明白为什么它在 IF 语句中不起作用。我确定我只是做了一些愚蠢的事情,但我终生无法弄清楚是什么。

使用后一种方法进行密码验证对我来说会是坏事还是被认为不好?

【问题讨论】:

  • 你的行 $success = password_v 缺少一个关闭)
  • 旁注: 在这一行。 if (!$query or $query == NULL),不需要or 部分。只要有if (!$query) 就足够了,因为它也可以覆盖null(这是假的)。
  • @MagnusEriksson 我想过这个,但我不确定,而且它在代码库中无处不在(非常旧)所以我还不想删除它。
  • if 语句中使用password_verify() 或将结果存储在变量中并进行检查没有区别。如果您发现了差异,则一定有其他错误,例如您传递了错误的密码或类似情况。

标签: php sql


【解决方案1】:

我似乎在这里的某个地方解决了这个问题:

if (!empty($_POST['password']))
{   
    while ($row = $query->fetch_assoc())
    {
        if (password_verify($_POST['password'], $row['password']))
        {                   
            $db->close();
            header("LOCATION: main.php");
            exit("EXIT: Logged in successfully.");
        }
        else
        {               
            header("LOCATION: index.php?error=Wrong password.");
            exit("EXIT: Wrong password");
        }
    }
}

我认为问题不是实际代码,而是我的数据库。我不知道它是否与它有关,但 phpmyadmin 显示我所有行的重复项。我对使用 SQL(今天)还是很陌生,所以我不知道这是否正常。也许我只需要给它时间来更新表格?谁知道呢。

【讨论】:

    【解决方案2】:
    1. 确保清理您的输入,永远不要简单地使用$_POST['password'],而是使用sanitize filter

    2. 对我来说,您的第一个代码块工作正常,而您的第二个代码块的括号不匹配。

    【讨论】:

    • 应该使用参数化而不是清理。 mysqli 函数会清理输入,但它存在已知缺陷,这就是参数化更好的原因。
    • ...当$_POST['password'] 从未发送到数据库或回显时,您为什么要对其进行清理?它只传递给password_verify(),这完全可以在没有任何卫生/逃逸的情况下完成。它实际上不应该被清理/转义,因为这实际上会更改密码。
    • 不要发布 cmets 作为答案。如果您没有足够的代表发表评论,请先进行处理。答案留给实际的解决方案。评论是一种特权,像这样试图绕过声望限制不是获得声望的好方法,恰恰相反。
    • @user3783243:没有 mysqli_real_escape_string() 没有缺陷,它只是让做真正愚蠢的事情成为可能。 OTOH 参数绑定可以通过隐式强制转换来中断函数调用,并且不支持变量列表。
    • @symcbean - “没有 mysqli_real_escape_string() 没有缺陷” - 是的,它确实……确实在边缘情况下,但它们确实存在:stackoverflow.com/questions/5741187/…
    猜你喜欢
    • 2018-02-02
    • 2019-01-26
    • 2013-02-28
    • 2021-10-17
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 2021-07-19
    相关资源
    最近更新 更多