我已经更新了代码,脚本仍然返回“失败”。信息。我必须遗漏一些东西,我已经听取了每个人的意见。那或者我只是愚蠢的大声笑!这是更新后的代码:
require('../connect.php');
$username = $_POST['username-sign-in'];
$password = $_POST['password-sign-in'];
if true then exit() for {
empty($username);
empty($password);
}
if (isset($username, $password)) {
$getuser = $connection->prepare('SELECT `username`, `password`
FROM `users` WHERE `username` = ?');
$getuser->bind_param('s', $username);
$getuser->execute();
$userdata = $getuser->get_result();
$row = $userdata->fetch_array(MYSQLI_ASSOC);
echo 'Password from form: ' . $password . '<br />';
echo 'Password from DB: ' . $row['password'] . '<br />';
if (password_verify($password, $row['password'])) {
echo 'Success.';
exit();
}
else {
echo 'Fail.';
exit();
}
}
else {
echo 'Please enter your username and password.';
$connection->close();
exit();
}
signup.php
require('../connect.php');
$ip = $_SERVER['REMOTE_ADDR'];
$username = $_POST['username-sign-up'];
$password = $_POST['password-sign-up'];
$hashedpassword = password_hash($_POST['password-sign-up'],
PASSWORD_BCRYPT, ['cost' => 12]);
$email = strtolower($_POST['email-sign-up']);
if true then exit() for {
empty($username)
empty($password)
empty($email)
!filter_var($email, FILTER_VALIDATE_EMAIL)
strlen($username) < 2 || strlen($username) > 32
strlen($password) < 6 || strlen($password) > 32
}
$usernameandemailcheck = $connection->prepare('SELECT `username`, `email`
FROM `users` WHERE `username` = ? AND `email` = ?');
$usernameandemailcheck->bind_param('ss', $username, $email);
$usernameandemailcheck->execute();
$result = $usernameandemailcheck->get_result();
$row = $result->fetch_array(MYSQLI_ASSOC);
// .. Username and email validation
if (isset($username, $hashedpassword, $email)) {
// Create and send mail
$query = $connection->prepare('INSERT INTO users (`ip`, `username`,
`password`, `email`) VALUES (?, ?, ?, ?)');
$query->bind_param('ssss', $ip, $username, $hashedpassword, $email);
$query->execute();
// SUCCESS
}
else {
// FAILURE
}
答案 0 :(得分:21)
您不能对输入进行哈希处理,然后在数据库中对其进行查询,因为哈希每次都会使用不同的随机盐。因此,您可以将相同的密码散列一千次并获得1000个不同的结果。
您只需在数据库中查询与用户名相关的记录,然后使用password_verify()
将DB返回的密码哈希值与输入密码进行比较。
此外,当最初在创建密码时将哈希值写入数据库(使用password_hash()
)时,无需转义哈希值。密码验证过程中根本没有使用password_hash()
。
答案 1 :(得分:4)
从快速浏览一下这些功能看来,你可能会以错误的方式进行测试。
您应该将密码的哈希版本存储在数据库中,然后将其与通过$ _POST提供的密码进行比较..其余的就像...
$getuser = $connection->prepare('SELECT `password`
FROM `users` WHERE `username` = ?');
$getuser->bind_param('s', $username);
$getuser->execute();
$userdata = $getuser->get_result();
$row = $userdata->fetch_array(MYSQLI_ASSOC);
echo 'Password from form: ' . $hashedpassword . '<br />';
echo 'Password from DB: ' . $row['password'] . '<br />';
if (password_verify($password, $row['password'])) {
// $password being $_POST['password-sign-in']
// $row['password'] being the hashed password saved in the database
echo 'Success.';
exit();
} else {
echo 'Fail.';
exit();
}
答案 2 :(得分:0)
您是否尝试更改'
的单引号:
$getuser = $connection->prepare('SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ?');
$getuser->bind_param('ss', $username, $hashedpassword);
要加倍"
$getuser = $connection->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ? AND `password` = ?");
$getuser->bind_param("ss", $username, $hashedpassword);
另外,为什么要与password
匹配?也许这适用于您的测试用例:
$getuser = $connection->prepare("SELECT `username`, `password` FROM `users` WHERE `username` = ?");
$getuser->bind_param("s", $username);
编辑此外,您在检查时基本上是对密码进行双重扫描:
if (password_verify($row['password'], $hashedpassword)) {
请改为:
if (password_verify($password, $row['password'])) {
问题是password_verify
的语法为:
boolean password_verify ( string $password , string $hash )
您需要在第一个参数中发送普通/非散列密码。然后将散列值放在第二个参数中。尝试一下。
答案 3 :(得分:-1)
问题通常是当您从表单中哈希用户输入时,它被散列为具有双引号。这就是为什么你看到以$ 2y $ 10开头的哈希......我认为你应该尝试从这一点开始解决它。如果你给出答案也要考虑这个