首页 > 解决方案 > PHP 8.0.7 password_verify 因错误而终止

问题描述

我正在为一个学校项目制作一个虚拟登录页面,并且我正在使用硬编码登录进行测试。但是,当我执行以下页面时:

<!DOCTYPE html>
<html>
<body>


<?php
$email = $password  = "";
$loginErr = $loginSuccess = "";

// Dummy login to replace the database
$correctEmail = htmlspecialchars("abc123@gmail.com");

$correctPassword =
    "\$2y\$10\$Ul2c6wZYxmO9MCJEnySdT.VnoRz7gAFOGVrAEOAhTFBM/5mp81Xl2";

if ($_SERVER["REQUEST_METHOD"] == "POST")
{
    $email = htmlspecialchars($_POST["email"]);
    $password = htmlspecialchars($_POST["password"]);
    echo gettype($password);
    echo gettype($correctPassword);
    echo password_verify($password, $correctPassword) or die("Something went wrong");

我得到以下输出:

字符串字符串出了点问题

无论我是否对哈希中的美元符号进行转义编码,我都会得到这个输出。

当我试图获取异常时:

try
    {
        echo password_verify($password, $correctPassword);
    }
    catch (Exception $e) { echo $e->getMessage();}

它没有打印任何东西。

php -l 对于任一版本的代码都没有返回语法错误。如标题所述,我使用的是 PHP 8.0.7,根据函数的手册页,它应该支持 password_verify。

你们中有人知道我怎样才能让这个功能工作吗?

编辑/解决方案:我假设函数没有返回,因为“echo verify_password($password, $correctPassword)”没有回显错误值。我现在知道,如果我想让它们出现,我必须将 false 值类型转换为 int。

其次,我认为如果哈希是 htmlspecialchars([password here]),那么使用 htmlspecialchars($_POST["password"]) 就可以了。从等式中删除 htmlspecialchars 完全解决了这个问题。

标签: php

解决方案


问题源于您使用htmlspecialchars(). htmlspecialchars()用于在将某些在 HTML 中有意义的字符发送到浏览器之前对其进行编码。它在这里没有位置。

因此,根据您的代码,我在我的开发服务器上进行了设置:

<!DOCTYPE html>
<html lang="en-GB">
<body>


<?php
$email = $password  = "";
$loginErr = $loginSuccess = "";

// Dummy login to replace the database
$correctEmail = "abc123@gmail.com";

$correctPassword =
    '$2y$10$PxZQRBaAG81cH1BCJowrxu7RaNnlm1i.Ls0l95ohU9rvsqqZr3guG';

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $email = $_POST["email"];
    $password = $_POST["password"];
    echo gettype($password);
    echo gettype($correctPassword);
    echo password_verify($password, $correctPassword) or die("Something went wrong");
} else {
    ?>
    <form method="POST">
        <input name="email"><br>
        <input name="password" type="password">
        <input type="submit" name="submit">
    </form>
<?php
}

我添加了一个用于测试的基本表单并将正确的密码哈希更改为“密码”的哈希,并删除了对htmlspecialchars().

它工作正常。

如果您htmlspecialchars()试图防御 SQL 注入,那么您选择了错误的函数。

快速解决方法是更改​​为使用mysqli_real_escape_string(). 但是,这不是最佳实践,您应该考虑重构代码以在根本不需要清理时使用准备好的语句。


推荐阅读