如何使用 password_verify() 从数据库中检索密码?

How to retrieve password from database with password_verify()?

我正在学习 PHP 作为一个项目,我开始构建一个社交网络。我确实创建了注册表单和登录表单,我可以将用户添加到我的数据库中。我也散列他们的密码。这是一个简单的站点,并且还在进行中,因此存在很多安全漏洞。

我的问题出在登录文件上,我似乎无法将用户与他给我的密码相匹配。为了验证用户密码,我使用了 password_verify() 函数,但它似乎无法正常工作。

这是我的代码:

报名

<?php
//signUp.php
//Here is where I add a user in my database
//I validate the input, confirm that the password is written like it  should be
//check if a user with the same username exists in the database
//if all checks out I will add the user in the database
   //and redirect the user to his profile
   require_once 'login.php';
   require_once 'helperFunctions.php';

$conn = new mysqli($servername, $username, $password, $database);

if(!$conn)
   die("Connection failed:" . mysqli_connect_error());

$myUsername = $_POST['Name'];
$myPassword = $_POST['Password'];
$myConfirm = $_POST['conPass'];

sanitize($conn, $myUsername);
sanitize($conn, $myPassword);

//check if the two passwords are the same

if($myPassword != $myConfirm){
  print "Your passwords don't match";
  header("refresh: 5; index.html");
} else {
   //check if username already exists in database
    $query = "SELECT * FROM members WHERE Username='$myUsername'";
    $result = mysqli_query($conn, $query);

    $count  = mysqli_num_rows($result);

    if($count == 0){
        //hash password
        $hashedPass = password_hash("$myPassword", PASSWORD_DEFAULT);

        //username doesn't exist in database 
        //add user with the hashed password
        $query ="INSERT INTO members (Username, Password) VALUES     ('{$myUsername}', '{$hashedPass}')";
        $result = mysqli_query($conn, $query);

        if(!$result)
            die("Invalid query: " . mysqli_error());
        else{
            print "You are now a member or The Social Network";
            header("refresh: 5; login_success.php");
        }

    } else {
        print "Username already exists";
        header("refresh: 5; index.html");
    }

}
?>

登录

<?php
//checkLogin.php
//Here is where I authenticate my users and if successfull I will show  them their profile
require_once 'login.php';
require_once 'helperFunctions.php';

$conn = new mysqli($servername, $username, $password, $database);

if(!$conn)
    die("Connection failed:" . mysqli_connect_error());

//Values from form
$myUsername = $_POST['Name'];
$myPassword = $_POST['Password'];

//sanitize input
sanitize($conn, $myUsername);
sanitize($conn, $myPassword);

$query = "SELECT * FROM members WHERE Username='$myUsername'";
$result = mysqli_query($conn, $query);
$count = mysqli_num_rows($result);

if($count == 1){
    $row = mysqli_fetch_array($result, MYSQLI_ASSOC);
    print "hashedPass = ${row['Password']}";
    print "myPassword: " . $myPassword;
    if(password_verify($myPassword, $row['Password'])){
        print "Password match";
    } else
        print "The username or password do not match";
} 
?>

清理功能

    function sanitize($conn, $val){
    $val = stripslashes($val);
    $val = mysqli_real_escape_string($conn, $val);
}

通过 运行 程序 print "hashedPass = ${row['Password']}"; 打印出散列密码,该密码与我在数据库中的密码相同,但由于某种原因,我被重定向到 print "The username or password do not match"; 语句之后

从已删除的答案中提取评论:

"I remembered that when I first created the database I used CHAR(10) for the passwords while the hashed password needs more characters."

所以这里的全能答案是你的密码栏是 50 个字符。

password_hash() 创建一个 60 个字符的字符串。

手册指出最好使用 VARCHAR,长度为 255,以适应未来的变化。

现在解决这个问题的方法是重新注册,然后使用您目前正在使用的内容重新登录。

手册中的示例:

<?php
/**
 * We just want to hash our password using the current DEFAULT algorithm.
 * This is presently BCRYPT, and will produce a 60 character result.
 *
 * Beware that DEFAULT may change over time, so you would want to prepare
 * By allowing your storage to expand past 60 characters (255 would be good)
 */
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";
?> 

上面的例子会输出类似于:

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

也来自手册:

Caution Using the PASSWORD_BCRYPT for the algo parameter, will result in the password parameter being truncated to a maximum length of 72 characters.

PASSWORD_DEFAULT - Use the bcrypt algorithm (default as of PHP 5.5.0). Note that this constant is designed to change over time as new and stronger algorithms are added to PHP. For that reason, the length of the result from using this identifier can change over time. Therefore, it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice).

PASSWORD_BCRYPT - Use the CRYPT_BLOWFISH algorithm to create the hash. This will produce a standard crypt() compatible hash using the "y$" identifier. The result will always be a 60 character string, or FALSE on failure.
Supported Options:

另一个comment/question从已删除的答案中提取:

"Can I alter my password field without having to delete my table and start from the beginning?"

答案是肯定的。在 Stack 上查看此问答:

  • How can I modify the size of column in a mysql table?

您还可以咨询:

旁注:您仍然需要为(旧)受影响的列重新输入新的哈希值。

另外,如前所述;您对 SQL 注入持开放态度。使用准备好的语句: