password_hash 和 password_verify 的问题,总是在一种情况下返回 true,在另一种情况下返回 false
Issue with password_hash and password_verify, always returning true in one case, false in another
我正在使用 password_hash 来保护数据库中的密码,但是当我使用 password_verify 时,它不匹配。在第一种情况下,我使用 password_verify 作为用户的连接,它总是 return true,即使它不是正确的密码。在第二种情况下,当用户想要更改密码时,我使用 password_verify ,要求他提供实际密码以进行更改。在这种情况下,它总是 return false,即使我以与连接相同的方式使用 password_verify。
在我的数据库中,密码存储为 VARCHAR(60)。我也试过 VARCHAR(255),没有区别。
这是我在用户创建帐户时使用 password_hash 的方式:
if(isset($_POST['username']) && isset($_POST['password']) && isset($_POST['psw-confirmation'])) {
$username = htmlspecialchars($_POST['username']);
$password = htmlspecialchars($_POST['password']);
$pswConfirmation = htmlspecialchars($_POST['psw-confirmation']);
if($password == $pswConfirmation) {
// Connection to database
require('database-connection.php');
$request = $database->prepare("SELECT * FROM users WHERE username = :username");
$request->execute(array(
":username" => $username
));
$return = $request->fetch();
// If the username doesn't exist yet in the database
if(!$return) {
$request->closeCursor();
$hash = password_hash($password, PASSWORD_BCRYPT);
$addProfile = $database->prepare("INSERT INTO users(username, password) VALUES(:username, :password)");
$addProfile->execute(array(
":username" => $username,
":password" => $hash
));
我想这部分工作正常,因为我的数据库中确实有一个散列密码:y$AFV2zouzirBhS30tCCRx9uyZDNMGSJWffUbXMO876T/9nJ8UDQJRi
以下是我验证连接密码的方法:
if(isset($_POST['username']) && isset($_POST['password'])) {
$username = htmlspecialchars($_POST['username']);
$password = htmlspecialchars($_POST['password']);
// Connection to database
require('database-connection.php');
$request = $database->prepare("SELECT * FROM users WHERE username = :username");
$request->execute(array(
":username" => $username
));
$return = $request->fetch();
$hash = $return['password'];
// If the username exists in the database
if($return) {
// And if the password match
if(password_verify($password, $hash)) {
echo "connected";
}
下面是当用户想要更改密码时我如何验证密码:
如果(isset($_POST['actual-psw']) && isset($_POST['new-psw']) && isset($_POST['confirm-psw'])) {
$actualPsw = htmlspecialchars($_POST['actual-psw']);
$newPsw = htmlspecialchars($_POST['new-psw']);
$confirmPsw = htmlspecialchars($_POST['confirm-psw']);
// Connection to database
require('database-connection.php');
$request = $database->prepare("SELECT * FROM users WHERE id = :id");
$request->execute(array(
':id' => $_SESSION['id']
));
$return = $request->fetch();
$hash = $return['password'];
if(password_verify($actualPsw, $hash)) {
echo "success";
} else {
echo "fail";
}
$_SESSION['id']
是 return 实际用户的正确 ID。
我不明白为什么它不起作用,这让我更加困惑,在一种情况下它总是正确的,而在另一种情况下它总是错误的,因为我在两种情况下都使用了相同的方式。
我发现我的错误在哪里了;
我有这个 database-connection.php 文件:
$host = 'localhost';
$dbname = 'japonwebsite';
$user = 'root';
$password = 'mysql';
try
{
$database = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user,
$password);
}
catch (Exception $e)
{
die('Erreur : ' . $e->getMessage());
}
我将此文件包含在所有需要连接到数据库的页面上,因此我将其包含在将用户添加到数据库的页面和验证登录的页面上。
事实是,在这两个页面上,我都在 $password = $_POST['password'];
将用户在登录或注册表单上输入的密码存储在变量中。
之后,我正在 include('database-connection.php');
连接数据库。所以 $password
总是等于 mysql
,因为我在 database-connection.php
中也有一个变量 $password
。所以我总是在数据库中添加“mysql”的散列,并始终验证数据库中的散列是否等于“mysql”,所以它总是正确的。我刚刚重命名了 database-connection 中的变量 $password 来修复它!
我正在使用 password_hash 来保护数据库中的密码,但是当我使用 password_verify 时,它不匹配。在第一种情况下,我使用 password_verify 作为用户的连接,它总是 return true,即使它不是正确的密码。在第二种情况下,当用户想要更改密码时,我使用 password_verify ,要求他提供实际密码以进行更改。在这种情况下,它总是 return false,即使我以与连接相同的方式使用 password_verify。
在我的数据库中,密码存储为 VARCHAR(60)。我也试过 VARCHAR(255),没有区别。
这是我在用户创建帐户时使用 password_hash 的方式:
if(isset($_POST['username']) && isset($_POST['password']) && isset($_POST['psw-confirmation'])) {
$username = htmlspecialchars($_POST['username']);
$password = htmlspecialchars($_POST['password']);
$pswConfirmation = htmlspecialchars($_POST['psw-confirmation']);
if($password == $pswConfirmation) {
// Connection to database
require('database-connection.php');
$request = $database->prepare("SELECT * FROM users WHERE username = :username");
$request->execute(array(
":username" => $username
));
$return = $request->fetch();
// If the username doesn't exist yet in the database
if(!$return) {
$request->closeCursor();
$hash = password_hash($password, PASSWORD_BCRYPT);
$addProfile = $database->prepare("INSERT INTO users(username, password) VALUES(:username, :password)");
$addProfile->execute(array(
":username" => $username,
":password" => $hash
));
我想这部分工作正常,因为我的数据库中确实有一个散列密码:y$AFV2zouzirBhS30tCCRx9uyZDNMGSJWffUbXMO876T/9nJ8UDQJRi
以下是我验证连接密码的方法:
if(isset($_POST['username']) && isset($_POST['password'])) {
$username = htmlspecialchars($_POST['username']);
$password = htmlspecialchars($_POST['password']);
// Connection to database
require('database-connection.php');
$request = $database->prepare("SELECT * FROM users WHERE username = :username");
$request->execute(array(
":username" => $username
));
$return = $request->fetch();
$hash = $return['password'];
// If the username exists in the database
if($return) {
// And if the password match
if(password_verify($password, $hash)) {
echo "connected";
}
下面是当用户想要更改密码时我如何验证密码: 如果(isset($_POST['actual-psw']) && isset($_POST['new-psw']) && isset($_POST['confirm-psw'])) {
$actualPsw = htmlspecialchars($_POST['actual-psw']);
$newPsw = htmlspecialchars($_POST['new-psw']);
$confirmPsw = htmlspecialchars($_POST['confirm-psw']);
// Connection to database
require('database-connection.php');
$request = $database->prepare("SELECT * FROM users WHERE id = :id");
$request->execute(array(
':id' => $_SESSION['id']
));
$return = $request->fetch();
$hash = $return['password'];
if(password_verify($actualPsw, $hash)) {
echo "success";
} else {
echo "fail";
}
$_SESSION['id']
是 return 实际用户的正确 ID。
我不明白为什么它不起作用,这让我更加困惑,在一种情况下它总是正确的,而在另一种情况下它总是错误的,因为我在两种情况下都使用了相同的方式。
我发现我的错误在哪里了;
我有这个 database-connection.php 文件:
$host = 'localhost';
$dbname = 'japonwebsite';
$user = 'root';
$password = 'mysql';
try
{
$database = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user,
$password);
}
catch (Exception $e)
{
die('Erreur : ' . $e->getMessage());
}
我将此文件包含在所有需要连接到数据库的页面上,因此我将其包含在将用户添加到数据库的页面和验证登录的页面上。
事实是,在这两个页面上,我都在 $password = $_POST['password'];
将用户在登录或注册表单上输入的密码存储在变量中。
之后,我正在 include('database-connection.php');
连接数据库。所以 $password
总是等于 mysql
,因为我在 database-connection.php
中也有一个变量 $password
。所以我总是在数据库中添加“mysql”的散列,并始终验证数据库中的散列是否等于“mysql”,所以它总是正确的。我刚刚重命名了 database-connection 中的变量 $password 来修复它!