Я использую 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
В моем столбце «password» указан этот тип данных: 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)
возвращает true, но password_verify($pass, $hash)
все равно возвращает false
Нашел проблему. когда я это сделал:
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/
Использование функции password_hash и password_verify PHP 5.5
Меня беспокоит одно: это предотвращает переключение кода. Как я узнаю, что хэш составляет 60 символов при изменении по умолчанию?
Только для справок в будущем. У меня была такая же проблема, что и пароли без причины. Когда я внимательно посмотрел на него, я увидел, что поле пароля в базе данных было недостаточно большим для хранения полного хеша, поэтому некоторые символы были отключены. После увеличения размера поля базы данных он работал отлично.
У меня была та же проблема, с которой вы работали, по какой-то причине, похоже, это помогает:
$hash = substr( $hash, 0, 60 );
в код, хотя моя строка уже имела длину 60 символов.