PHP - проверка password_hash ()

Следующий код должен быть прямым и простым, вставка в базу данных при регистрации создает хеш, но позже, когда я пытаюсь войти в систему с тем же паролем, хэш, который он создает, не соответствует тому, что находится в базе данных (я имел print_r для проверки). Может кто-нибудь увидеть, если я просто не замечаю чего-то тупого?

session_start();
require_once("login.php");
$error = "";
$email = "";
$password = "";

if (isset($_GET['logout'])) {
    unset($_SESSION['id']);
    setcookie('id', '', time() - 60*60);
    $_COOKIE['id'] = "";
} else {
    if (isset($_SESSION['id']) or isset($_COOKIE['id'])) {
        header("Location: loggedinpage.php");
    }
}

if (isset($_POST["submit"])) {
    $link = mysqli_connect($hn, $un,$pw,$db);
    if ($link->connect_error) die("Fatal Errror.");
    if (!$_POST["email"]) {
        $error . = "An email address is required<br>";
    }
    if (!$_POST["password"]) {
        $error . = "A password address is required<br>";
    }
    if ($error != "") {
        $error= "<p>There were error(s) in your form:</p>".$error;
    } else {
        if ($_POST['signup'] == 1) {
            $email = mysqli_real_escape_string($link, $_POST['email']);
            $password = mysqli_real_escape_string($link,$_POST['password']);
            $query = "SELECT id FROM `users` WHERE email = '".$email."' LIMIT 1";
            $result=$link->query($query);
            if (mysqli_num_rows($result) > 0) {
                $error = "That email address is taken.";
            } else {
                $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
                $query = "INSERT INTO `users`(`email`,`password`) VALUES ('".$email."', '".$hashedPassword."')";

                if (!mysqli_query($link,$query)) {
                    $error = "<p>Could not sign you up, please try again later</p>";
                } else {
                    $_SESSION['id'] = mysqli_insert_id($link);
                    if (isset($_POST['stayLoggedIn']) and $_POST['stayLoggedIn'] == 1) {
                        setcookie('id', mysqli_insert_id($link), time()+60*60*24);
                    }
                    header("Location: loggedinpage.php");
                }
            }
        } else {
            $email = mysqli_real_escape_string($link, $_POST['email']);
            $password = mysqli_real_escape_string($link, $_POST['password']);
            $hashedPassword = password_hash($password,PASSWORD_DEFAULT);
            $query = "SELECT * FROM users WHERE email = '".$email."' LIMIT 1";
            $result = $link->query($query);
            if ($result->num_rows > 0) {
                $row = $result->fetch_array(MYSQLI_ASSOC);
                if ($email == $row['email'] and password_verify($password,$row['password'])) {
                    if (isset($_POST['stayLoggedIn']) and $_POST['stayLoggedIn'] == 1) {
                        setcookie('id', $row['id'], time()+60*60*24);
                        header("Location: loggedinpage.php");
                    }  
                } else {
                    $error = "Incorrect Username/Password combination";
                }
            }
        }
    }
}

Похоже, это проблема отладки. Вы можете взглянуть на этот статья.

Amessihel 22.11.2018 16:50
stackoverflow.com/a/268269/10111639
TsV 22.11.2018 16:51

Было бы лучше использовать подготовленные операторы вместо ручного объединения строк. Или просто используйте подходящую библиотеку аутентификации PHP и не изобретайте велосипед при регистрации / аутентификации пользователя. Но, как говорили другие, чтобы помочь себе, покажите, что вы пробовали и где застряли во время отладки.

slhck 22.11.2018 16:52

Вы хешируете экранированный пароль вместо введенного. Но поскольку вы делаете это также при проверке, это должно прекратиться. Вам также не нужен $email==$row['email'], поскольку вы уже ищете это электронное письмо в запросе к базе данных, хотя поиск в БД будет нечувствительным к регистру, и это сравнение чувствительно к регистру. Вы вводили E-Mail с таким же регистром при входе в систему?

Karsten Koop 22.11.2018 17:02

Подтвердите тип и размер столбца базы данных, в котором вы храните хэши.

miken32 22.11.2018 17:40

@ miken32 извините, пришлось отправиться прямо на День благодарения, прежде чем опубликовать его. Спасибо, хотя я считаю, что теперь это была проблема с размером столбца хешируемого пароля. Собираюсь попытаться исправить это

zsebacher 22.11.2018 22:31

Вы можете подтвердить размер и тип?

miken32 22.11.2018 22:32

электронная почта - varchar (50), и я изменил пароль на varchar (255), ранее он тоже был на 50, но по-прежнему возникает та же проблема.

zsebacher 22.11.2018 22:44

Теперь он работает, но только тогда, когда у меня установлен флажок оставаться в системе. Обратите внимание, что я удалил перенаправление заголовка на уровень ниже. Я понимаю, что когда я опубликовал, это было связано с тем, что нужно было войти в систему, но после перемещения оттуда он не будет перенаправлять, если я не поставлю этот флажок.

zsebacher 22.11.2018 22:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
9
84
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

пытаться

  if (password_verify($password, (string)$row->password)){
             //Your Code
            }

из-за функции password_verify возврат только Boolean true или false

И

$hashedPassword = password_hash($password,PASSWORD_DEFAULT);

Добавляйте только один раз, когда вы вставляете в Sql (новый пользователь)

Ответ принят как подходящий

Хотя он спрятан в конце абзаца, Документация PHP действительно говорит, что «рекомендуется сохранить результат в столбце базы данных, размер которого может превышать 60 символов (255 символов было бы хорошим выбором)».

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


У вас есть еще несколько проблем:

  • Вы изменяете пароль перед генерацией хэша (с mysqli_real_escape_string())
  • Вы не используете подготовленные заявления
  • Похоже, вы полагаетесь на файлы cookie для аутентификации. Файлы cookie - это данные, созданные пользователями, им нельзя доверять! Вот почему PHP обеспечивает поддержку сеансов, потому что данные хранятся на сервере.
  • Вы не должны проверять существующий адрес электронной почты с помощью запроса, вместо этого вы должны иметь уникальный индекс, установленный в столбце электронной почты в базе данных.

Другие вопросы по теме