【发布时间】:2026-01-27 19:10:01
【问题描述】:
我尝试使用函数 password_verify 使用发布的用户密码和数据库中的哈希来检查密码。
首先,我如何生成密码和哈希:
$user_password = $this->generate_password();
private function generate_password($length = 8)
{
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-=+;:,.?";
$password = substr( str_shuffle( $chars ), 0, $length );
return $password;
}
define("HASH_COST_FACTOR", "10");
$hash_cost_factor = (defined('HASH_COST_FACTOR') ? HASH_COST_FACTOR : null);
$user_password_hash = password_hash($user_password, PASSWORD_DEFAULT, array('cost' => $hash_cost_factor));
$sql = "INSERT INTO users (user_name, user_password_hash, user_email, user_creation_timestamp)
VALUES (:user_name, :user_password_hash, :user_email, :user_creation_timestamp)";
$query = $this->db->prepare($sql);
$query->execute(array(':user_name' => $user_name,
':user_password_hash' => $user_password_hash,
':user_email' => $user_email,
':user_creation_timestamp' => $user_creation_timestamp));
$count = $query->rowCount();
if ($count != 1) {
$_SESSION["feedback_negative"][] = FEEDBACK_ACCOUNT_CREATION_FAILED;
return false;
}
if ($this->sendUserpassword($user_email, $user_password)) {
$_SESSION["feedback_positive"][] = FEEDBACK_ACCOUNT_SUCCESSFULLY_CREATED;
return true;
} else {
$query = $this->db->prepare("DELETE FROM users WHERE user_id = :last_inserted_id");
$query->execute(array(':last_inserted_id' => $user_id));
$_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_MAIL_SENDING_FAILED;
return false;
}
private function sendUserpassword($user_email, $user_password)
{
$mail = new PHPMailer;
if (EMAIL_USE_SMTP) {
$mail->IsSMTP();
$mail->SMTPDebug = PHPMAILER_DEBUG_MODE;
$mail->SMTPAuth = EMAIL_SMTP_AUTH;
if (defined(EMAIL_SMTP_ENCRYPTION)) {
$mail->SMTPSecure = EMAIL_SMTP_ENCRYPTION;
}
$mail->Host = EMAIL_SMTP_HOST;
$mail->Username = EMAIL_SMTP_USERNAME;
$mail->Password = EMAIL_SMTP_PASSWORD;
$mail->Port = EMAIL_SMTP_PORT;
} else {
$mail->IsMail();
}
$mail->From = EMAIL_PASSWORD_FROM_EMAIL;
$mail->FromName = EMAIL_PASSWORD_FROM_NAME;
$mail->AddAddress($user_email);
$mail->Subject = EMAIL_PASSWORD_SUBJECT;
$mail->Body = EMAIL_PASSWORD_CONTENT . '/' . $user_password;
if($mail->Send()) {
$_SESSION["feedback_positive"][] = FEEDBACK_PASSWORD_MAIL_SENDING_SUCCESSFUL;
return true;
} else {
$_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_MAIL_SENDING_ERROR . $mail->ErrorInfo;
return false;
}
}
登录验证:
if (!isset($_POST['user_name']) OR empty($_POST['user_name'])) {
$_SESSION["feedback_negative"][] = FEEDBACK_USERNAME_FIELD_EMPTY;
return false;
}
if (!isset($_POST['user_password']) OR empty($_POST['user_password'])) {
$_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_FIELD_EMPTY;
return false;
}
$sth = $this->db->prepare("SELECT user_id,
user_name,
user_email,
user_password_hash,
user_active,
user_account_type
FROM users
WHERE (user_name = :user_name OR user_email = :user_name)");
$sth->execute(array(':user_name' => $_POST['user_name'], ':provider_type' => 'DEFAULT'));
$count = $sth->rowCount();
if ($count != 1) {
$_SESSION["feedback_negative"][] = FEEDBACK_LOGIN_FAILED;
return false;
}
$result = $sth->fetch();
//check via password_verify
if (password_verify($_POST['user_password'], $result->user_password_hash)) {
...
return true;
} else {
$_SESSION["feedback_negative"][] = FEEDBACK_PASSWORD_WRONG;
return false;
}
总是得到密码错误信息。我读了这个php password_hash and password_verify issues no match,但我手动测试了哈希字符串以使用文字字符串进行验证。
哈希字符串: $2y$10$SwSq7OukPpN/QJ8YOdKgquJQ28fQbNY1Q3JdTFnoe.2VxD/D2RXBS
通过电子邮件发送的密码: /f)1c(-JG
手工测试:
$hash = '$2y$10$SwSq7OukPpN/QJ8YOdKgquJQ28fQbNY1Q3JdTFnoe.2VxD/D2RXBS';
$password = '/f)1c(-JG';
if (password_verify($password, $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
打印无效密码。
【问题讨论】:
-
您的数据库列是否足够长以存储未截断的整个哈希?
-
是 user_password_hash VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL
-
您能否提供一个显示问题的最小测试用例?因为
password_函数本身工作正常,并且您似乎 可以正确使用它们。但是,这里有很多我们看不到也无法调试的部分。 -
我可以发布孔创建过程,但 mvc 很大。我添加了 smtp 发送过程。也许sendet密码错误?但我不这么认为,因为它与 generate_password 的输出相同。
-
我准确地要求minimal示例,而不是everything。尝试自己减少问题。如果您有一个多步骤过程中出现问题,请尝试首先关注那件事并确认它完全有效。然后一步步把问题扩大到你原来的范围。
标签: php mysql hash passwords verify