我将密码存储在数据库中,如下所示:
public function add_user($username, $password){
$password = password_hash($password, PASSWORD_DEFAULT); //here
$this->query = $this->conn->prepare('INSERT INTO users (username, password) VALUES (:username, :password)');
$this->query->bindParam(':username', $username);
$this->query->bindParam(':password', $password);
$this->query->execute();
}
但是,我不知道如何检索它。我知道函数
password_verify($password, $hash)
但我不确定如何使用它。如何使用它从数据库中获取用户?
使用以下代码验证密码的最佳方式是什么:
public function get_user($username, $password){
$this->query = $this->conn->prepare('SELECT * from users WHERE username=:username AND password=:password');
$this->query->bindParam(':username', $username);
$this->query->bindParam(':password', $password);
$this->query->execute();
$this->retrieve = $this->query->fetchAll(PDO::FETCH_ASSOC);
}
任何帮助或指导都会很棒。这种逻辑让我非常困惑。
答案 0 :(得分:3)
首先,+1使用PHP的密码函数进行密码哈希!
与正常哈希函数(例如md5()
,sha1()
等 - 不应用于密码哈希)相反,password_hash()
将每次都使用相同的密码生成不同的哈希,因为它会自动为每个哈希生成一个随机盐。这是一个很棒的功能,可以使您的密码哈希更加安全,但这意味着您无法使用password_hash()
哈希输入的密码,并在SQL查询中使用该哈希密码(与用户名相结合)来检索用户。
相反,只需根据用户名检索用户 - 然后使用password_verify()
将检索到的密码哈希值与输入的密码进行比较。此功能可以将输入的密码与存储的哈希进行比较,即使成本或算法已更改。
示例(使用您的代码):
public function get_user($username, $password)
{
$this->query = $this->conn->prepare('SELECT * from users WHERE username=:username LIMIT 1');
$this->query->bindParam(':username', $username);
$this->query->execute();
$user = $this->query->fetch(PDO::FETCH_ASSOC);
if (password_verify($password, $user['password']) {
// password is correct, return the user
return $user;
} else {
// incorrect password
return false;
}
}
正如我之前所说,新密码API允许升级新生成的密码哈希的强度,而不会破坏旧密码。这是因为成本和算法(以及顺便说一句,盐)都存储在散列中。
建议随着时间的推移增加成本,因为可用硬件变得更强(减少攻击者强制密码所需的时间)。
如果您决定这样做,或者您决定使用其他哈希算法,请不要忘记在登录过程中使用password_needs_rehash()
添加支票。这样,现有密码也将被重新散列。
如果函数(使用数据库中的哈希作为参数调用)返回true,则只需再次运行password_hash()
并使用新哈希覆盖数据库中的旧哈希。这显然只能在用户登录时完成,因为这是您应该有权访问纯文本密码的唯一时间。
答案 1 :(得分:2)
使用
检索用户记录SELECT * from users WHERE username=:username
将从数据库中检索到的密码与用户输入的密码进行比较