Как правильно использовать password_verify с PDO?

#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 за объяснение этого мне