使用password_hash()在登录时保护密码


Using password_hash() to protect password on login?

作为编程和php的新手,但渴望学习,我很快就发现了所谓的"最佳"answers"坏"实践。糟糕的做法是使用MD5加密,例如,我即将学习和实现。但是,我最近才了解到相对较新的password_hash()函数,它可以自动执行很多(是的,我没有使用"很多"这个词:D)加密过程,例如添加盐。如果我说错了请指正。

所以我在这里有一个关于如何正确使用这个函数的问题。

function login_check() {
    $connection = database();
    $name = $_POST['name'];
    $password = $_POST['password'];
    $password_hash = password_hash($password, PASSWORD_DEFAULT);
    $query = "SELECT id FROM users WHERE name = ? AND password = ?";
    $stmt = mysqli_prepare($connection, $query);
    mysqli_stmt_bind_param($stmt, 'ss', $name, $password);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_store_result($stmt);
    $counter = mysqli_stmt_num_rows($stmt);
    if($counter > 0 && password_verify($name, $password_hash)){
        $_SESSION['login'] = $name;
        header('location:../../index.php');
        exit;
    }
    else {
        header('location:../../failed.php');
        exit;
    }
}
if(isset($_POST['name']) && isset($_POST['password'])){
    login_check();
}

所以这就是我走了多远,说实话,我不确定这是不是正确的方式。可能需要你的反馈。这样可以吗?或者还有其他的事情需要考虑吗?

我读到没有必要再创建自己的盐和其他哈希相关的东西了

注册时,password_hash将输入的密码存储在您的数据库中。

在登录时:

  1. 根据用户名从数据库中获取散列密码,例如:

    SELECT password FROM users WHERE name = ?
    
  2. 用刚刚输入的密码验证散列密码:

    if (password_verify($_POST['password'], $databaseResult['password'])) {
        // match
    }
    

not :

  • password_hash登录后的任何内容
  • SELECT ... WHERE password = ?在登录时,因为你需要存储哈希的随机盐,以便再次产生相同的哈希,所以你不能在数据库
  • 中通过哈希搜索任何东西

您需要在password_verify()函数中传递$password而不是$name

所以改变

password_verify($name, $password_hash)

password_verify($password , $password_hash)

注意:- password_verify()需要您的密码和密码存储在您的数据库中。不是你的散列密码。

还需要在数据库中存储散列密码。

并将您的密码与散列

进行比较
 mysqli_stmt_bind_param($stmt, 'ss', $name, $password_hash);

总体思路是通过用户名(email)查询数据库,并使用散列密码检索用户详细信息。然后,使用输入的密码和数据库中的OLD散列运行password_verify()。如果匹配,则返回true。

我没有测试代码,但它应该为您提供如何正确使用这些函数的示例。

<?php
function login_check()
{
    $connection = database();
    $name = $_POST['name'];
    $password = $_POST['password'];
    $query = "SELECT password FROM users WHERE name = ?";
    $stmt = mysqli_prepare($connection, $query);
    mysqli_stmt_bind_param($stmt, 'ss', $name);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_store_result($stmt);
    $counter = mysqli_stmt_num_rows($stmt);
    $user = mysqli_stmt_fetch($stmt); // retrieve old user password
    if ($counter > 0 && password_verify($name, $user['password'])) {
        $_SESSION['login'] = $name;
        header('location:../../index.php');
        exit;
    } else {
        header('location:../../failed.php');
        exit;
    }
}
if (isset($_POST['name']) && isset($_POST['password'])){
    login_check();
}