#php #mysql #pdo #password-encryption
#php #mysql #pdo #пароль-шифрование
Вопрос:
Кажется, я не могу заставить password_verify работать с моим кодом php PDO. Мое поле pass хранится как varchar(255). Я читал похожие вопросы, но из того, что я могу сказать, у меня все настроено правильно. Должно быть, я все еще что-то упускаю. Моя страница регистрации выглядит следующим образом..
$user = $_POST['username']
$pass = $_POST['pass'];
$passH = password_hash($pass, PASSWORD_DEFAULT);
$query = $con->prepare("INSERT INTO emps (user, pass) VALUES (?, ?)");
$query->execute([$user, $passH]);
Зашифрованный пароль теперь успешно сохранен в моей базе данных.
Моя страница входа выглядит следующим образом..
if(isset($_POST['login'])) {
$username = $_POST['username'];
$pass = trim($_POST['pass'];
$passH = password_hash($pass, PASSWORD_DEFAULT);
$sel_user = $con->prepare("SELECT id, username, pass, gid FROM emps WHERE gid!=4 AND username=?");
$sel_user->execute([$username]);
$check_user=$sel_user->fetch();
if(count($check_user)>0 amp;amp; password_verify($passH, $check_user['pass'])) {
$_SESSION['username']=$check_user['username'];
header("Location: xadmin.php");
exit;
}
else {
echo "<script>alert('Not Found')</script>";
Тело страницы входа в систему..
<form action="login.php" method="post">
<table width="100%" border="0">
<tbody>
<tr>
<td bgcolor="#3B3B3B" height ="35" class="BodyTxtB" align="center">Administrator Login</td></tr>
<tr height="20"><td></td></tr>
<tr>
<td class="BodyTxtB" align="center">Username</td>
</tr>
<tr>
<td class="BodyTxtB" align="center"><input type="text" class="BodyTxtBC" name="username" required="required"/></td>
</tr>
<tr height="20"><td></td></tr>
<tr>
<td class="BodyTxtB" align="center">Password</td>
</tr>
<tr>
<td class="BodyTxtB" align="center"><input type="password" class="BodyTxtBC" name="pass" required="required"/></td>
</tr>
<tr height="20"><td></td></tr>
<tr height="35"><td align="center"><input type="image" src="images/btn_login.jpg" name="login" value="Login"/>
<input type="hidden" name="login" value="Login" /></td></tr>
<tr height="20"><td></td></tr>
</tbody>
</table>
</form>
Кто-нибудь может обнаружить какие-либо ошибки?
Комментарии:
1. phpdelusions.net/pdo/password_hash
2. зачем вам хэшировать пароль перед его проверкой?
3. Вы неправильно используете password_hash . Вам необходимо ввести текстовый пароль с хэшированным паролем (из базы данных). Кроме того, почему вы обрезаете пароль?
4. Хорошо, я удалю обрезку пароля. Также у меня не должно быть
$passH = password_hash($pass, PASSWORD_DEFAULT);
на моей странице входа в систему?
Ответ №1:
Аргументами для password_verify()
являются (1) незашифрованный пароль, который вы хотите проверить, и (2) хэшированный пароль, который вы используете в качестве ссылки. Вы хэшируете первый аргумент перед сравнением:
$pass = trim($_POST['pass'];
$passH = password_hash($pass, PASSWORD_DEFAULT);
// ...
if(count($check_user)>0 amp;amp; password_verify($passH, $check_user['pass'])) {
Вы должны делать password_verify($pass /** the unhashed one */, $check_user['pass'])
Кроме того, обрезка пароля — плохая идея. Что, если пароль на самом деле содержит пробелы (что вы должны разрешить ему делать)?
Комментарии:
1. Спасибо, я пробовал это, но это все еще не работает. Теперь, когда я нажимаю «Отправить», форма входа исчезает, но я не перенаправляюсь на страницу, и мое сообщение об ошибке не отображается
2. @craisondigital Проверьте журнал ошибок и консоль браузера. Скорее всего, вы ввели синтаксическую ошибку или неправильное перенаправление в логику страницы входа.
Ответ №2:
RTM? http://php.net/password_verify
boolean password_verify ( string $password , string $hash )
Вы передаете ОТКРЫТЫЙ текстовый пароль для $password
. Вы не хэшируете его самостоятельно. Это просто сгенерирует НОВЫЙ хэш с ДРУГОЙ солью, делая сравнения бессмысленными и невозможными.
password_verify
извлекает правильную соль $hash
, использует ее для хеширования $password
, а затем сравнивает хэш-строки.
например, password_verify — это в основном просто это:
function password_verify($pw, $hash) {
$salt = get_salt_from($hash);
$temp = password_hash($pw, $salt);
return ($temp == $hash);
}
Комментарии:
1. Довольно забавно, как PHP все упрощает, серьезно, две функции для всего?, но людям все равно удается все усложнять. $ temp === $hash для этой дополнительной меры.
2. ну,
get_salt_from()
может быть немного сложнее, но в остальном, да. password_verify — это, по сути, просто удобство.3. Спасибо @MarcB за объяснение этого мне