Как проверить пароль пользователя из базы данных mysql

У меня проблема с проверкой пароля пользователя из моей базы данных mySQL. Сначала я хэширую свой пароль и записываю его в свою БД:

Сначала мой обработчик регистрации:

class RegisterHandler
{
    /**
     * @var RegisterQuery
     * 
     */
    private $register;

    /**
     * @var HashPassword
     *
     */
    private $HashPassword;

    /**
     * @var string
     *
     */
    private $getUsername;

    /**
     * @var string
     *
     */
    private $username;

    public function __construct()
    {
        $this->username = $_POST['username'];
        $this->register = new RegisterQuery;
        $this->checkUsername = new SelectUsernameQuery;
        $this->HashPassword = new HashPassword($_POST['password']);
    }

    public function execute()
    {
        $hashedPassword = $this->HashPassword->getHashedPassword();
        $salt = $this->HashPassword->getSalt();

        $dbUser = $this->checkUsername->execute($this->username);
        $dbUser->bindValue( 1, $this->username);
        $dbUser->execute();

        if( !$dbUser->rowCount() == 0 ) { # If rows are found for query
            echo "Username found";
            return;
        }

        $this->register->execute($this->username, $hashedPassword, $salt, $_POST['name']);

    }
}

Вы можете видеть, что я хэширую свой пароль в функции выполнения с помощью этого кода: (забудьте о соли, я ее больше не использую)

class HashPassword
{
    /**
     * @var string
     * 
     */
    private $salt = 'x';

    /**
     * @var string
     * 
     */
    private $hashedPassword;

    public function __construct($password)
    {
        $this->hashedPassword = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
        $this->getHashedPassword();
    }

    public function getHashedPassword()
    {
        return $this->hashedPassword;
    }
}

после хеширования пароля я записываю хэш в базу данных.

А теперь мой вопрос: как мне получить пароль от БД, чтобы проверить его?

я попробовал это:

class LoginHandler
{

    private $databaseWrapper;

    /**
     * @var SelectUsernameQuery
     * 
     */
    private $checkUsername;

    private $checkPassword;

    /**
     * @var string
     *
     */
    private $enteredUsername;

    /**
     * @var string
     *
     */
    private $enteredPassword;

    /**
     * @var HashPassword
     *
     */
    private $passwordHasher;

    public function __construct()
    {
        $this->databaseWrapper = new DatabaseWrapper;
        $this->checkUsername = new SelectUsernameQuery;
        $this->checkPassword = new SelectPasswordQuery;
        $this->enteredUsername = $_POST['username'];

        $this->passwordHasher = new HashPassword($this->enteredPassword);
    }

    private function createSessionName()
    {
        $_SESSION['name'] = $this->enteredUsername;
    }

    public function execute()
    {
        $this->verifyUser();
    }

    private function verifyUser()
    {
        $this->enteredPassword = $_POST['password'];
        $userDBHash = $this->checkPassword->execute($this->enteredUsername);
        $userDBHash->execute();
        if(password_verify($this->enteredPassword, $userDBHash))
        {
            echo 'password is valid';
        }

        $dbUsername = $this->checkUsername->execute($this->enteredUsername);
        $dbUsername->bindValue( 1, $this->enteredUsername);
        $dbUsername->execute();

        if( !$dbUsername->rowCount() == 0 ) { # If rows are found for query
            echo 'Username: '."$this->enteredUsername".' was found!';
            $this->createSessionName();
            return;
        }

        echo 'Ups, This Username: '."$this->enteredUsername".' was not found!';    }
    }
}

В классе verifyUser я записываю введенный пароль в переменную. После этого я получаю хэш из БД в $userDBHash с помощью этого запроса:

private function getUsername($username)
{
    return $this->databaseWrapper->getPDO()->prepare(
           "SELECT password FROM users WHERE username = '$username'");
}

После этого я пытаюсь password_verify($this->enteredPassword, $userDBHash), но получаю следующую ошибку:

Warning: password_verify() expects parameter 2 to be string, object given in /var/www/c2b/src/Handlers/LoginHandler.php on line 72

person lukas    schedule 03.06.2016    source источник
comment
Итак, что же содержат $this->enteredPassword и $userDBHash? Один из них не строка, а что-то другое.   -  person 1615903    schedule 03.06.2016
comment
$enteredPassword содержит пароль, который вызывается $_POST, а $userDBHash содержит хэш пароля в базе данных. Так это массив правильно? Как я могу преобразовать его?   -  person lukas    schedule 03.06.2016
comment
Я не знаю, что содержит $userDBHash, так как код, который его устанавливает, не виден, однако в сообщении об ошибке достаточно четко указано, что это не строка, а объект. Из вашего кода я бы предположил, что это может быть PDOStatement: $userDBHash->execute();   -  person 1615903    schedule 03.06.2016
comment
Как писал @1615903, переменная $userDBHash должна содержать хэш, хранящийся в базе данных. Согласно сообщению об ошибке, он не содержит строки.   -  person martinstoeckli    schedule 03.06.2016
comment
Как я писал в вопросе: в классе verifyUser я записываю введенный пароль в переменную. После этого я получаю хэш из БД в **$userDBHash с этим private function getUsername($username) { return $this->databaseWrapper->getPDO()->prepare( "SELECT password FROM users WHERE username = '$username'"); }   -  person lukas    schedule 03.06.2016
comment
Эта функция не возвращает хэш, она возвращает PDOStatement.   -  person 1615903    schedule 03.06.2016
comment
Функция также не вызывается нигде в вашем коде, который вы разместили. Кроме того, его имя сбивает с толку - getUsername, но, по-видимому, он должен возвращать хешированный пароль для конкретного пользователя?   -  person 1615903    schedule 03.06.2016
comment
Как бы вы позвонили пользователю? Да, он должен возвращать хеш определенного пользователя   -  person lukas    schedule 03.06.2016


Ответы (1)


Кажется, ваша проблема заключается в том, как получить хэш пароля из базы данных. Я сделал быстрый пример из своей головы (не проверенный), но он должен помочь вам начать.

private function getPasswordHashFromDatabase($username)
{
  $pdo = $this->databaseWrapper->getPDO();
  $stmt = $pdo->prepare('SELECT password FROM users WHERE username = ?');
  $stmt->bindParam(1, $username);
  if ($stmt->execute())
  {
    if ($row = $stmt->fetch())
    {
      return $row[0];
    }
  }
  return '';
}

Обратите внимание на ? в операторе select, использование подготовленных операторов защищает ваше приложение от SQL-инъекций.

person martinstoeckli    schedule 03.06.2016
comment
** Редактировать Это работает очень хорошо! Сначала я потерпел неудачу.. Я никогда не делал $_POST для пароля.. теперь это работает :) Большое спасибо! - person lukas; 04.06.2016