在 PDO 准备语句中验证 password_hash()
Verifying password_hash() in PDO prepared statements
我正在尝试使用 bcrypt 算法对密码进行哈希处理,但我 运行 遇到了几个问题。首先,我找不到合适的地方来检查 password_verify()
returns 是否为真。
$admin = $_POST['admin-user'];
$pass = $_POST['admin-pass'];
$password_hash = password_hash($pass, PASSWORD_BCRYPT);
if (isset($admin)&&isset($pass)&&!empty($admin)&&!empty($pass)) {
$admin_select = $link->prepare("SELECT `id` FROM `admins` WHERE `username` = :admin");
$admin_passwd = $link->prepare("SELECT `password` FROM `admins` WHERE `username` = :admin_pw");
$admin_passwd->execute(array(':admin_pw' => $admin));
$admin_pwd = $admin_passwd->fetch(PDO::FETCH_ASSOC);
if (password_verify($pass, $admin_pwd)){
if ($admin_select->execute(array(':admin' => $admin))) {
$res = $link->query('SELECT COUNT(*) FROM requests');
$query_num_rowz = $res->fetchColumn();
if ($query_num_rowz == 0) {
echo 'No records found';
} else if ($query_num_rowz > 0) {
$query = $link->prepare("SELECT id FROM admins WHERE username = :admin");
$query->execute(array(':admin' => $admin));
$admin_id = $query->fetch(PDO::FETCH_ASSOC);
$_SESSION['admin_id'] = $admin_id;
header('Location: index.php');
}
}
}
}
其次,我不确定这是 select 用户密码的正确方法。
$admin_passwd = $link->prepare("SELECT `password` FROM `admins` WHERE `username` = :admin_pw");
$admin_passwd->execute(array(':admin_pw' => $admin));
$admin_pwd = $admin_passwd->fetch(PDO::FETCH_ASSOC);
由于您没有将 ->fetch
放入循环中,因此单次调用将 return 一行关联数组。您必须首先访问正确的索引(在本例中为 password
)。然后将 password_verify
内的行值(至少如果已经散列)与用户输入进行比较。粗略示例:
if(!empty($_POST['admin-user'] && !empty($_POST['admin-pass']))) {
$admin = $_POST['admin-user'];
$pass = $_POST['admin-pass'];
$admin_info = $link->prepare("SELECT `password` FROM `admins` WHERE `username` = :admin_user");
$admin_info->execute(array(':admin_user' => $admin));
$row = $admin_info->fetch(PDO::FETCH_ASSOC);
if(!empty($row)) {
// check if the hashed row password
if(password_verify($pass, $row['password'])) {
// okay
}
} else {
// not found
}
}
我正在尝试使用 bcrypt 算法对密码进行哈希处理,但我 运行 遇到了几个问题。首先,我找不到合适的地方来检查 password_verify()
returns 是否为真。
$admin = $_POST['admin-user'];
$pass = $_POST['admin-pass'];
$password_hash = password_hash($pass, PASSWORD_BCRYPT);
if (isset($admin)&&isset($pass)&&!empty($admin)&&!empty($pass)) {
$admin_select = $link->prepare("SELECT `id` FROM `admins` WHERE `username` = :admin");
$admin_passwd = $link->prepare("SELECT `password` FROM `admins` WHERE `username` = :admin_pw");
$admin_passwd->execute(array(':admin_pw' => $admin));
$admin_pwd = $admin_passwd->fetch(PDO::FETCH_ASSOC);
if (password_verify($pass, $admin_pwd)){
if ($admin_select->execute(array(':admin' => $admin))) {
$res = $link->query('SELECT COUNT(*) FROM requests');
$query_num_rowz = $res->fetchColumn();
if ($query_num_rowz == 0) {
echo 'No records found';
} else if ($query_num_rowz > 0) {
$query = $link->prepare("SELECT id FROM admins WHERE username = :admin");
$query->execute(array(':admin' => $admin));
$admin_id = $query->fetch(PDO::FETCH_ASSOC);
$_SESSION['admin_id'] = $admin_id;
header('Location: index.php');
}
}
}
}
其次,我不确定这是 select 用户密码的正确方法。
$admin_passwd = $link->prepare("SELECT `password` FROM `admins` WHERE `username` = :admin_pw");
$admin_passwd->execute(array(':admin_pw' => $admin));
$admin_pwd = $admin_passwd->fetch(PDO::FETCH_ASSOC);
由于您没有将 ->fetch
放入循环中,因此单次调用将 return 一行关联数组。您必须首先访问正确的索引(在本例中为 password
)。然后将 password_verify
内的行值(至少如果已经散列)与用户输入进行比较。粗略示例:
if(!empty($_POST['admin-user'] && !empty($_POST['admin-pass']))) {
$admin = $_POST['admin-user'];
$pass = $_POST['admin-pass'];
$admin_info = $link->prepare("SELECT `password` FROM `admins` WHERE `username` = :admin_user");
$admin_info->execute(array(':admin_user' => $admin));
$row = $admin_info->fetch(PDO::FETCH_ASSOC);
if(!empty($row)) {
// check if the hashed row password
if(password_verify($pass, $row['password'])) {
// okay
}
} else {
// not found
}
}