B
B
Burjuazi2018-10-26 02:28:46
PHP
Burjuazi, 2018-10-26 02:28:46

How to verify passwords with the database?

I categorically welcome everyone!
I broke my head, although I know for sure that everything is simple. The problem is this.
It is necessary to fasten the reconciliation of the entered password with the password hash in the database at the entrance.
Here is the registration, the password enters the database in the form of a hash, everything seems to be OK here.

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;
    }

And here is the login code
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;
    }

And here is the checkUserData code
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;
    }

Knowledgeable and experienced, tell me how to do it right, as well as what can be improved in the code?
I understand that verification is carried out through password_verify (), but how to do it right - I can’t figure it out.
And as I understand it, you need to check all the data entered by users, how to implement it better? And what other vulnerabilities could there be? And immediately a question, so as not to produce several questions. What do backticks in table and field names give? those. What is the difference between `user` and user in SQL query?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
F
FanatPHP, 2018-10-26
@Burjuazi

Correct answer

// Достанем юзера по мылу
$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";
}

There is only one variable in the request, so it makes no sense to arrange scribbling with named placeholders.
The query may not return a single row, and if this is not checked, there will be an error.
Well, the name of the field in the table is quite readable from the query.
About other questions. There is such a thing as a search engine. It helps you find answers to questions on your own. The most popular are google.com and yandex.ru. And it really works. Just try:
What do backticks in table and field names do?
password_hash and PDO

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question