@Burjuazi

Как сверить пароли с базой?

Категорически всех приветствую!
Голову сломал, хотя знаю наверняка что всё просто. Проблема такова.
Надо прикрутить на входе сверку введёного пароля с хэшем пароля в базе.

Вот регистрация, пароль в базу попадает в виде хэша, тут вроде как всё ОК.
public function actionRegister() {

        $name = '';
        $email = '';
        $password = '';
        $result = false;

        if (isset($_POST['submit'])) {
            $name = $_POST['name'];
            $email = $_POST['email'];
            $password = $_POST['password'];
            $passwordHash = password_hash($password, PASSWORD_ARGON2I);
            $errors = false;

            if (!User::checkName($name)) {
                $errors[] = 'Имя должно быть не короче 2-х символов!';
            }

            if (!User::checkEmail($email)) {
                $errors[] = 'Неправильный E-mail!';
            }

            if (!User::checkPassword($password)) {
                $errors[] = 'Пароль должен быть не короче 6-и символов!';
            }

            if (User::checkEmailExists($email)) {
                $errors[] = 'Такой E-mail уже есть!';
            }

            if ($errors == false) {
                $result = User::register($name, $email, $passwordHash);
            }
        }
        require_once 'views/user/register.php';

        return true;
    }


А вот код входа
public function actionLogin() {

        $email = '';
        $password = '';

        if (isset($_POST['submit'])) {
            $email = $_POST['email'];
            $password = $_POST['password'];
            
            $errors = false;

            if (!User::checkEmail($email)) {
                $errors[] = 'Неправильный E-mail!';
            }

            if (!User::checkPassword($password)) {
                $errors[] = 'Пароль должен быть не короче 6-и символов!';
            }
            
            $userId = User::checkUserData($email, $password);

            if ($userId == false) {
                $errors[] = 'Неверный E-mail или пароль!';
            } else {
                User::auth($userId);

                header("Location: /cabinet/");
            }
        }
        require_once 'views/user/login.php';

        return true;
    }


И вот код checkUserData
public static function checkUserData($email, $password) {

        $db = Db::getConnection();
        $sql = 'SELECT * FROM `user` WHERE `email` = :email AND `password` = :password';

        
        $result = $db->prepare($sql);
        $result->bindParam(':email', $email, PDO::PARAM_STR);
        $result->bindParam(':password', $password, PDO::PARAM_STR);
        $result->execute();
        
        $user = $result->fetch();
        
        if ($user) {
            return $user['id'];
        }
        return false;
    }


Знающие и опытные, подскажите как правильно сделать, а так же что можно улучшить в коде?
Понимаю, что сверка осуществляется через password_verify(), но как правильно сделать - никак не допру.

И я так понимаю нужна проверка всех вводимых пользователеями данных, как ее реализвать лучше? И какие еще уязвимости тут могут быть? И сразу вопрос, чтобы не плодить несколько вопросов. Что дают обратные апострофы в именах таблиц и полей? т.е. `user` и user в SQL запросе чем отличаются?
  • Вопрос задан
  • 480 просмотров
Решения вопроса 1
FanatPHP
@FanatPHP
Чебуратор тега РНР
Правильный ответ
// Достанем юзера по мылу
$sql = 'SELECT * FROM `user` WHERE `email` = ?';
$result = $db->prepare($sql);
$result->execute([$email]);
$user = $result->fetch();

// потом сверим его хеш пароля с паролем из формы
if ($user && password_verify($_POST['password'], $user['password'])) {
 echo "it's ok";
}

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

По поводу остальных вопросов. Есть такая штука, поисковая машина. Она помогает находить ответы на вопросы самостоятельно. Самыми популярными являются google.com и yandex.ru. И это реально работает. Просто попробуй:
Что дают обратные апострофы в именах таблиц и полей?
password_hash и PDO
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы