PHP密码哈希在创建哈希时验证,但在MySQL查询时验证失败



我正在构建一个仪表板系统,在树莓派上运行Apache,并为所有新用户预生成密码及其散列。

我用来做这个的行是password_hash('Password1@', PASSWORD_DEFAULT)

用户首次登录时显示密码重置窗口。在此密码重置页面,用户点击提交后,我可以成功使用password_hash()password_verify()

第一次登录工作得很好,但在注销后的任何登录尝试都会导致password_verify()失败。

What I Have check/Tried

  • 设置数据库中的密码属性为varchar(255)
  • 单个用户行检索,我可以从中返回数据。
  • PASSWORD_DEFAULTPASSWORD_ARGON2ID都这样做。

Things I Know

  • 数据库为utf8mb4_unicode_ci.
  • 用户设置的新密码成功推送到数据库。
    • 我已经添加了一个if语句来检查新的哈希是否可以被验证。
  • 哈希字符串匹配SELECT返回的内容,因为它应该。
  • 我在PHP 7的其他项目中使用了下面的函数。这个项目是在PHP 8上。(这是问题吗?)

密码重置功能

public function firstLoginUpdatePassword($username, $password, $confirm, $token)
{
if ($password != $confirm)
{
header("Location: first-login?mismatch&token=" . $token);
exit;
}
else
{
$newPassword = password_hash($password, PASSWORD_DEFAULT);
$token = bin2hex(openssl_random_pseudo_bytes(16));
try
{
$stmt = $this->con->prepare("UPDATE Account SET Password=:password, isFirstLogin=FALSE, Token=:token WHERE Username=:username");
$stmt->bindparam(":username", $username);
$stmt->bindparam(":password", $newPassword);
$stmt->bindparam(":token", $token);
if ($stmt->execute())
{
header("Location: home");
exit;
}
else
{
header("Location: first-login?error&token=" . $token);
exit;
}
}
catch (PDOException $ex)
{
echo $ex->getMessage();
}
}
}
<<p>登录功能/strong>
public function Login($user, $pwd)
{
try
{
$stmt = $this->con->prepare("SELECT Username, Password FROM Account WHERE Username=:username or Email=:username;");
$stmt->bindparam(":username", $user);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($stmt->rowCount() == 1)
{
if (password_verify($pwd, $row['Password']))
{
try
{
$stmt = $this->con->prepare("UPDATE Account SET LastLogin=CURRENT_TIMESTAMP WHERE Username=:username;");
$stmt->bindparam(":username", $row['Username']);
if ($stmt->execute())
{
$_SESSION['userSession'] = $row['Username'];
return true;
}
else
{
header("Location: login?error-other");
exit;
}
}
catch (PDOException $ex)
{
echo $ex->getMessage();
}
}
else
{
header("Location: login?error-credential");
exit;
}
}
else
{
header("Location: login?error-login");
exit;
}
}
catch(PDOException $ex)
{
echo $ex->getMessage();
}
}

解决方案在文件编码的某个地方。我在服务器上的PHP文件中混合了各种编码。我将所有文件递归地重新编码为UTF-8,现在问题已经解决了。

最新更新