mysql — php password_verify не работает с базой данных

Я использую PHP 5.4 с этим сценарием обратной совместимости: https://github.com/ircmaxell/password_compat/blob/master/lib/password.php

это не должно иметь значения, потому что я могу заставить процесс хеширования и проверки работать в моей функции регистрации:

$hash = password_hash($pass, PASSWORD_DEFAULT);

echo $pass;
echo $hash;

if( password_verify($pass,$hash) )
echo 'success';
else echo 'failure';

//success is always shown

//EXAMPLE INPUT
$pass = 'password';

//EXAMPLE OUTPUT
password$2y$10$JK1jumvvSIm/gP3fWE3k9O98MzvHKDRYCjRPBniYg9riACyQw7WYSsuccess

но всякий раз, когда я пытаюсь сохранить хеш в базе данных MySQL, а затем извлечь его для функции проверки, он всегда завершается неудачей. Вот моя функция входа в систему:

function user_login( $mysqli, $email, $pass ){

$err_msg = 'login: '.$mysqli->error.' | '.$email;

if( $stmt = $mysqli->prepare('SELECT password FROM users WHERE email=?') ) :

if( !$stmt->bind_param('s', $email) ) log_sql_error( $err_msg );
if( !$stmt->execute() ) log_sql_error( $err_msg );
if( !$stmt->bind_result( $hash ) ) log_sql_error( $err_msg );
if( $stmt->fetch() === FALSE ) log_sql_error( $err_msg );
if( !$stmt->close() ) log_sql_error( $err_msg );

//I can see that these values are identical to the ones
//echoed out in the registration function
echo $pass;
echo $hash;

if( password_verify($pass,$hash) )
echo 'success';
else echo 'failure';

else : log_sql_error( $err_msg );
endif;
}
//failure is always shown

//EXAMPLE INPUT
$pass = 'password';

//EXAMPLE OUTPUT
password$2y$10$JK1jumvvSIm/gP3fWE3k9O98MzvHKDRYCjRPBniYg9riACyQw7WYSfailure

Мой столбец «пароль» имеет этот тип данных: VARCHAR(255) NOT NULL

Ошибки php не отображаются, поэтому единственное, о чем я могу думать, это то, что значение хеш-функции не форматируется таким же образом, когда оно выходит из базы данных, когда оно входит, но когда я выводю значения, они выглядят как идентичны.

Как еще можно отладить это / что не так с моим кодом?

Спасибо

ОБНОВИТЬ:

Это определенно связано с кодировкой:

$hardcode_hash = '$2y$10$JK1jumvvSIm/gP3fWE3k9O98MzvHKDRYCjRPBniYg9riACyQw7WYS';

echo $hash;
echo '<br/>';
echo $hardcode_hash;
echo '<br/>';

if( $hash == $hardcode_hash )
echo 'success';
else echo 'failure';

//OUTPUT
$2y$10$JK1jumvvSIm/gP3fWE3k9O98MzvHKDRYCjRPBniYg9riACyQw7WYS
$2y$10$JK1jumvvSIm/gP3fWE3k9O98MzvHKDRYCjRPBniYg9riACyQw7WYS
failure

Как мне переформатировать значение SQL, чтобы соответствовать выводу password_hash? Вот что я попробовал:

(string)$hash
utf8_encode($hash)

если я сделаю:

$hash = settype($hash,"string");

if($hash == $hardcode_hash) возвращает истину, но password_verify($pass, $hash) все еще возвращает ложь

11

Решение

Нашел проблему. когда я сделал это:

echo strlen($hash)

он напечатал 90, что странно, потому что в конце, когда я распечатывал сообщение об успехе / неудаче, точно не было пробелов, а поле имеет длину varchar 255

Я добавил эту строку:

$hash = substr( $hash, 0, 60 );

И теперь работает нормально.

Странно, что никто больше не сталкивался с этой проблемой. Есть похожие сообщения о password_verify, но ни один из них не требовал такого типа преобразования или какого-либо преобразования в этом отношении:

php password_verify не работает

password_verify php не совпадает

http://forums.phpfreaks.com/topic/283407-need-help-with-password-verify/

Использование PHP 5.5 функции password_hash и password_verify

Одна вещь, которая беспокоит меня, — это предотвращение прямой совместимости кода. Как я узнаю, что при изменении значения по умолчанию хеш имеет длину 60 символов?

11

Другие решения

Просто для дальнейшего использования. У меня была та же самая проблема с паролями, терпящими неудачу без причины. Когда я присмотрелся к нему, я увидел, что поле пароля в базе данных было недостаточно большим, чтобы хранить полный хэш, поэтому некоторые символы были обрезаны. После увеличения размера поля базы данных все заработало отлично.

2

У меня была та же проблема, что и у вас, когда она не работала, по какой-то причине она, кажется, помогает поставить:

$hash = substr( $hash, 0, 60 );

в код, хотя моя строка была уже 60 символов.

2

У меня была та же проблема, и она все еще не работала, несмотря на то, что мои столбцы базы данных были varchar (255), что хэши были 60 символами, и что все мои кодировки были UTF-8. Я довольно новичок в PHP и SQL, поэтому я не буду притворяться, что точно понимаю, почему это работает, но мне удалось это исправить, поэтому я надеюсь, что этот пост поможет другим людям с такой же проблемой.

Оказалось, что основной причиной, по которой password_verify () не проверял мои хэши, было то, что я сделал подготовленный оператор, который использовал хранимую процедуру ранее в скрипте, не извлекая все результаты из запроса, чтобы очистить буфер перед закрытием и повторное открытие соединения для выполнения следующего запроса. Вызов next_result () для mysqli_link после закрытия оператора гарантирует, что все результаты будут использованы.
Кроме того, я использовал другой подготовленный оператор с хранимой процедурой для вставки пароля, но мне все еще нужно было вызывать store_result () и free_result (), даже если наборы результатов не возвращались из вставки. Я предполагаю, что сочетание этих вещей повредило мои данные где-то вдоль линии, в результате чего password_verify () возвращал false на казалось бы идентичных хешах.

Этот ответ было для другой проблемы, но я нашел это полезным для изучения, как правильно закрыть подготовленные операторы с помощью хранимых процедур.

1
По вопросам рекламы [email protected]