Здравствуйте. Пишу форму авторизации. Пользователь находится, но пароль проверку не проходит. Запрос из переменной $query_select_email успешно находит нужную ячейку (проверял через phpMyAdmin), однако password_verify($pwd, $result2) всегда false. HTML: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Syte</title> </style> </head> <body> <form method="post" action="login.php"> <input type="text" id="user_email" name="user_email" placeholder="e-mail" pattern=".+@.+\..+"> <input type="password" id="user_password" name="user_password" placeholder="пароль"> <input type="submit" name="submit" value="войти"> </form> </body> </html> PHP: <?php require '../db.inc.php'; $email = trim($_POST['user_email']); $email = $mysqli->real_escape_string($email); $pwd = trim($_POST['user_password']); $pwd = $mysqli->real_escape_string($pwd); $query_select_email="SELECT email FROM users WHERE email = '$email'"; $query_select_hash="SELECT pwd FROM users WHERE email = '$email'"; $result = $mysqli->query($query_select_email); // $result2 = mysqli_query($mysqli, $query_select_hash); $result2 = $mysqli->query($query_select_hash); if ($result->num_rows == 1) { echo 'Такой пользователь есть.'; } else { echo 'Такого пользователя нет.'; } if (password_verify($pwd, $result2)) { echo 'Пароль верный.'; $query_select_hash->close(); $mysqli->close(); } else { echo 'Пароль неверный!'; $query_select_hash->close(); $mysqli->close(); } ?>
сделайте var_dump($result2), будете удивлены. $result2 в данном случае не хэш содержит, а ресурс, который, надо обработать, из которого надо сформировать массив результатов, и уже потом, из массива результатов доставать хэш. --- Добавлено --- Вот вам для затравки: https://php.net/manual/ru/mysqli-result.fetch-array
Спасибо PHP: while ($row = $result2->fetch_row()) { printf ($row[0]); } Выводит хеш из таблицы. Только что потом делать? $row[0] уничтожается после завершения цикла, насколько я понимаю. И $result тоже нужно обрабатывать?
Без цикла он мне ничего не выводит. fetchColumn - а это довольно интересно. Можно будет им воспользоваться, через PDO я тоже пробовал подключаться.
Как что? Присвоить это значение переменной, объявленной вне цикла. PHP: $query_result = []; while ($row = $result2->fetch_row()) { $query_result[] = $row; } var_dump($query_result[0]); Вот и вытащили наружу. Любой результат работы БД надо обрабатывать. В итоге вы придете к тому, что напишете свой универсальный обработчик запросов. Советовать всем подряд PDO - не правильно, вот что я скажу. Если в проекте не планируется использовать ничего, окромя мускула, PDO - это зло. Ты сейчас возразишь про prepared statement, но они и в mysqli есть.
Ну просто обычно это главный аргумент. Просто вот ради этого: ворошить PDO, как по мне, нет смысла. Проблемы как таковой и нет.
Да, нет. У нас не индия, чтобы приложение по количеству строчек оценивать. К тому же, есть куча готовых классов, а можно и свой написать обработчик, который будет в одну строку все что угодно делать. PDO - монстр, с огромными накладными расходами на свое существование, с огромными оверхедами. Он нужен только если у тебя офигеть кросс-платформа, заточенная на миграцию между разными БД. В любом другом случае он не нужен. Это узкое бутылочное горлышко, существование которого может оправдать только необходимость оперативной миграции. Советовать PDO новичкам, которым он во сто лет не пригодится - медвежья услуга.
пластинка... где там совет чтобы юзер переходил на пдо ? тут не Индия а Африка оказывается когда говорится одно, а берут и через *опу другое лепят
Ты не оскорбляйся. Ничего, чтобы тебя обидеть, я не написал. Я лишь аргументирую свою точку зрения. И тот факт, что ты всегда всем рекомендуешь PDO, тоже имеет место быть. И ты имеешь на это право - это твое дело, кому что рекомендовать. У тебя есть положительный личный опыт использования PDO, ты им делишься. Ты хочешь, чтобы все были рады как ты. Это ок. И это правильное, хорошее, стремление. Но ты закрываешь глаза на оборатную сторону этой медали. А я ее осветил. Всего лишь описал свою точку зрения на этот счет. Что считаю использование PDO там, где это не оправдано архитектурно, не правильным подходом. Не более.
девочки не ссорьтесь --- Добавлено --- проблема топикстартера не в выборе расширения или метода, а в непонимании самого алгоритма. зачем там цикл? то же самое с уважаемым советчиком. зачем там подобная "оптимизация", если она не помогает? --- Добавлено --- @evkon, ты допускаешь, что может быть несколько аккаунтов с одним email? если так, это ошибка проектирования. если сие невозможно, то цикл не нужен.
@artoodetoo, email проверяется на стадии регистрации, поэтому несколько аккаунтов с одним email в базе не может быть. Хорошо, теперь без цикла и оставил только один запрос к базе данных, из него можно вытащить и email, и хеш. Однако всё-равно где-то у меня ошибка, password_verify всегда возвращает false. Для поля pwd, где хранится хеш выделил char(255). Я только начал, поэтому ещё многое не знаю. PHP: <?php require '../db.inc.php'; $email = trim($_POST['user_email']); $email_escape_string = $mysqli->real_escape_string($email); $pwd = trim($_POST['user_password']); $pwd_escape_string = $mysqli->real_escape_string($pwd); $query_select_email="SELECT * FROM `users` WHERE email = '$email_escape_string'"; $result = $mysqli->query($query_select_email); if ($row = $result->fetch_assoc()) { echo 'Такой пользователь есть'; if (password_verify($pwd_escape_string, $row['pwd'])) echo '. и пароль тоже верный.<br/><a href="">На главную!</a>'; else echo ', но пароль неверный!';} else echo 'Такого пользователя нет.'; $query_select_email->close(); $mysqli->close(); ?>
В базе хоть хэш хранится? Созданный соотв. ф-цией. Зачем вы пароль эскейпите, если не используете его в запросе? --- Добавлено --- Это много. Даже для алгоритмов с длинной суммой. Или у вас соль стопудовая?
Не конвертируется в char (60), мало ему, честно, не считал сколько нужно. Да, вы правы, пароль на стадии сравнения с хешем, наверное, излишне обрабатывать. Хеш в таблице есть, успешно достаётся (на предыдущий странице проверяли), пробовал другие email, не получается. PHP: <?php include '../db.inc.php'; include 'pwgen.class.php'; $email = trim($_POST['email']); $email = $mysqli->real_escape_string($email); $pwgen = new PWGen(); $pwd = $pwgen->generate(); $pwd_hash = password_hash('$pwd', PASSWORD_DEFAULT); $query_select_email="SELECT email FROM users WHERE email = '$email'"; $result = $mysqli->query($query_select_email); if ($result->num_rows >= 1){ echo "Такой пользователь уже есть!"; $query_select_email->close(); $mysqli->close(); } else{ $mysqli->query("INSERT INTO users (email, pwd) VALUES ('$email', '$pwd_hash')"); $mysqli->close(); $subject = "Ты принят!"; $msg = "Используй для входа e-mail: $email и пароль: $pwd"; $headers = 'From: *@*.*'; mail($email, $subject, $msg, $headers); printf('Зарегистрирован! Проверь почтовый ящик.<br/><a href="..">На главную!</a>'); } ?>
Попробуйте при входе использовать пароль $pwd (4 символа) --- Добавлено --- Логика добавления неправильная. Так с БД обычно не работают. Нужно сделать мыло первичным ключом или юником и делать вставку без предварительной выборки, а потом уже смотреть на результат.
Можно поподробнее, я не совсем понял. Пароль у меня генерируется через класс, на выходе 8 символов, его хеш заносится в таблицу, пароль отправляется на email, с ним я и пытаюсь войти. На какой стадии мне нужно использовать $pwd (4 символа)? У меня id первичный ключ, так не очень? Как вставка может предшествовать выборке, нам же email нужно проверить на наличие его в таблице, я совсем запутался.
Я имел в виду, что вам нужно попробовать ввести при входе в качестве пароля $pwd (для любого пользователя) – думаю, будете сильно удивлены Если первичный ключ другой, используйте юник (уникальный индекс).
Всё, теперь дошло. Убрал кавычки. Моя самая большая ошибка в том, что шех от этих четырёх символов $pwd я принял за шех от значения переменной $pwd и думал, что в таблице у меня лежит шех пароля. Спасибо вам большое. По поводу уникальности email тоже понял. Здесь нужно обрабатывать исключение через try catch или if (mysqli) хватит? А я только с num_rows научился работать Вообще, с помощью форума код стал короче, что не может не радовать.
Хватит if. Посмотрите, что возвращает query для таких запросов, как INSERT. --- Добавлено --- Пока не вижу, как это можно использовать. Я вам на киберфоруме показал, что для определения наличия строки в результате выборки это абсолютно лишнее.
Один мальчик любил фреймфорки, кроссплатформенность, абстракции и оверхеды, другой же любил экономить, монолиты и был уверен, что вся эта новомодная хрень ни кому не нужна. Когда же бутылочным горлышком оказались не эти-ваши-фреймворки, а отсутствие даже теоретической возможности нормально масштабироваться, свои, домашние решения начали выдавать непредвиденные глюки, согласно фазе Луны, первому мальчику поручили все это разгребать. Дык вот, с тех пор он люто шлет лучи ненависти всем, кто вместо того, что бы прививать новичкам нормальные подходы лезет со своими нужно-не-нужно. Ушел.