Привет, я устал выполнять и отлаживать эту задачу. Я прочитал несколько похожих вопросов на Stackoverflow.com, но не нашел решения. Проблема в том, что, несмотря на использование одного и того же метода хеширования (предположим, md5, hash) как для регистрации, так и для входа в систему, каждый раз, когда я пытаюсь войти в систему, отображается несоответствующий пароль.
Я использую класс InsertUsers, в котором есть метод с именем userLogin, которому я отправляю два аргумента (userName и userPassword) из файла login.php. Перед отправкой в качестве аргумента я зашифровал пароль. Но там написано непревзойденный пароль.
Когда я проверил пароль, отправленный login.php после хеширования, я обнаружил эту строку $ 2y $ 10 $. / SyQEE.LiMBynyanGXmeei1lk / fgZrQ / K4V6PBpjsc3nlBMh6gd6 вместо сохраненной строки (хранящейся на странице регистрации) $ 2y $ 10 $ 1vrJ3kmIGOFGG.
Помимо несогласованной проблемы, каждый раз, когда я ввожу один и тот же пароль, хешированный пароль страницы входа в систему выглядит немного иначе. Ниже приведен код, который я использовал. Пожалуйста, помогите мне разобраться в проблеме. Я задал несколько вопросов в Stackoverflow, но ни один из них не подошел для моей проблемы.
В registration.php я зашифровал вот так -
$user_pass = password_hash($_POST['password'], PASSWORD_DEFAULT);
И в классе InsertUsers в моем методе userLogin есть
public function userLogin($userName, $userPassword){
try{
$sql = "SELECT id FROM users WHERE user_name = ? AND password = ?";
$stmt = $this->connect()->prepare($sql);
$stmt->bindParam(1, $userName,PDO::PARAM_STR);
$stmt->bindParam(2, $userPassword,PDO::PARAM_STR);
$stmt->execute();
if ($stmt->rowCount() > 0){
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result['id'];
}
else{
return false;
}
}
catch (PDOException $e) {
echo 'Error, Please put correct data' .$e->getMessage();
}
}
В файле login.php я зашифровал пароль перед отправкой его вышеуказанному методу.
if ((empty($_POST['username'])) || empty($_POST['password'])){
array_push($error_message, "User Name & Password required");
}
else{
$userName = $_POST['username'];
$userPassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
}
if (empty($error_message)){
$Login = new InsertUsers();
$loginCheck = $Login->userLogin($userName, $userPassword);
if ($loginCheck > 0){
$_SESSION['username'] = $_POST['username'];
echo "Hello ". $_SESSION['username'];
}
else{
echo "password not matched";
}
}






password_hash() не возвращает каждый раз один и тот же хэш, поэтому используйте password_verify().
public function userLogin($userName, $userPassword){
try{
$sql = "SELECT id FROM users WHERE user_name = ? AND password = ?";
$stmt = $this->connect()->prepare($sql);
$stmt->bindParam(1, $userName,PDO::PARAM_STR);
$stmt->bindParam(2, $userPassword,PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
$hashed_password = $row['password'];
}
if ($stmt->rowCount() > 0){
if (password_verify($userPassword, $hashed_password)) {
return $result['id'];
}
}
else{
return false;
}
}
catch (PDOException $e) {
echo 'Error, Please put correct data' .$e->getMessage();
}
}
Также вам следует увеличьте длину вашего столбца до 255 символов.
Спасибо, что сообщили мне длину. Но уверены ли вы, что get_result () и fetch_assoc () работают таким образом в PDO? Я использую PDO. Кроме того, следует ли отправлять пароль от login.php в хешированной форме? Или послать в виде обычного текста?
@AsDictionary Нет проблем, он должен работать и должен быть отправлен в виде обычного текста.
Если я отправлю пароль в виде простого текста, как мой оператор sql будет сравнивать его с хешированным паролем, хранящимся в базе данных, и извлекать его для проверки в более поздней части кода?
@AsDictionary password_verify() проверит простой текстовый пароль с хешированным в базе данных.
Это я понимаю. Но как мой оператор SQL будет получать данные для проверки с помощью функции password_verify (), где пароль базы данных (которая хешируется) = $ userPassword (это простой текст). Поскольку оба они не равны, оператор sql не будет извлекать ни одной строки, не так ли?
@AsDictionary Я думаю, вы можете просто получить строку с правильным именем пользователя
Вы не можете искать хешированный и соленый пароль с помощью Sql, хеш будет выглядеть по-разному для каждого вычисления. Взгляните на этот пример кода, он показывает, как вы можете проверить пароль.