0 follower

Аутентификация пользователя

Наше приложение должно различать владельца системы и гостей. Поэтому мы должны реализовать функцию пользовательской аутентификации.

Вы, возможно, заметили, что каркас приложения уже реализует аутентификацию, проверяя, являются ли имя пользователя и пароль значениями demo и admin. В этом разделе мы изменим соответствующий код так, чтобы аутентификация происходила посредством таблицы User БД.

Аутентификация пользователя выполняется в классе, который реализует интерфейс IUserIdentity. Для этой цели каркас приложения использует класс UserIdentity. Класс находится в файле /wwwroot/blog/protected/components/UserIdentity.php.

Подсказка: В соответствии с соглашением, название файла класса должно быть таким же как имя класса плюс расширение .php. Можно обратиться к классу, используя псевдоним пути. Например, мы можем обратиться к классу UserIdentity используя псевдоним application.components.UserIdentity. Многие методы API в Yii могут распознать псевдонимы пути (например, Yii::createComponent()). Это позволяет избежать использования абсолютных путей в коде, которые создают неприятности при развертывании приложения.

Модифицируем класс UserIdentity следующим образом:

<?php
class UserIdentity extends CUserIdentity
{
    private $_id;
 
    public function authenticate()
    {
        $username=strtolower($this->username);
        $user=User::model()->find('LOWER(username)=?',array($username));
        if($user===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if(!$user->validatePassword($this->password))
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {
            $this->_id=$user->id;
            $this->username=$user->username;
            $this->errorCode=self::ERROR_NONE;
        }
        return $this->errorCode==self::ERROR_NONE;
    }
 
    public function getId()
    {
        return $this->_id;
    }
}

В методе authenticate() мы используем класс User для поиска строки в таблице tbl_user, в которой значение поля username такое же, как полученное имя пользователя без учета регистра. Помните, что класс User был создан, используя инструмент gii в предыдущем разделе. Поскольку класс User наследуется от класса CActiveRecord, мы можем использовать возможности ActiveRecord для того, чтобы обращаться к таблице tbl_user в ОО манере.

Для того, чтобы проверить, ввёл ли пользователь правильный пароль, мы вызываем метод validatePassword класса User. Нам необходимо изменить файл /wwwroot/blog/protected/models/User.php как показано ниже. Отметим, что вместо хранения пароля в БД в явном виде, мы сохраняем его хеш. При проверке введённого пользователем пароля, вместо сравнения паролей, мы должны сравнивать хеши. Для хеширования пароля и его проверки мы используем входящий в Yii класс CPasswordHelper.

class User extends CActiveRecord
{
    ......
    public function validatePassword($password)
    {
        return CPasswordHelper::verifyPassword($password,$this->password);
    }
 
    public function hashPassword($password)
    {
        return CPasswordHelper::hashPassword($password);
    }
}

В классе UserIdentity мы также переопределяем метод getId(), который возвращает значение id пользователя, найденного в таблице tbl_user. Родительская реализация возвратила бы имя пользователя вместо id. И username и id будут сохранены в сессии и доступны через Yii::app()->user в любом месте нашего кода.

Подсказка: В классе UserIdentity мы используем CUserIdentity без явного подключения соответствующего файла. Это возможно т.к. CUserIdentity — один из классов ядра фреймворка Yii. Yii будет автоматически подключать файл класса для любого класса ядра, когда к нему обратятся впервые. То же возможно с классом User т.к. он расположен в директории /wwwroot/blog/protected/models, которая была добавлена к параметру include_path PHP в конфигурации приложения следующим образом:

return array(
    …
    'import'=>array(
        'application.models.*',
        'application.components.*',
    ),
    …
);

Конфигурация выше говорит, что любой класс, файл которого расположен в директории /wwwroot/blog/protected/models или /wwwroot/blog/protected/components, будет автоматически подключен, когда к классу обратятся впервые.

Класс UserIdentity используется классом LoginForm для аутентификации пользователя, основанной на введенных имени и пароле, полученных на странице входа в систему. Следующий фрагмент кода показывает как используется класс UserIdentity:

$identity=new UserIdentity($username,$password);
$identity->authenticate();
switch($identity->errorCode)
{
    case UserIdentity::ERROR_NONE:
        Yii::app()->user->login($identity);
        break;
    …
}

Информация: Люди часто путаются в идентификации (identity) и компоненте приложения user. Первая представляет способ выполнения аутентификации, в то время как последний используется, чтобы представить информацию, связанную с текущим пользователем. У приложения может быть только один компонент user, но один или несколько классов идентификации, в зависимости от того, какую аутентификацию поддерживает приложение. При аутентификации, экземпляр идентификации может передать некоторую информацию компоненту user. Эта информация будет глобально доступна через компонент user.

Чтобы проверить изменённый класс UserIdentity, мы можем открыть адрес http://www.example.com/blog/index.php и попытаться войти с именем пользователя и паролем, которые мы храним в таблице tbl_user. Если мы используем базу данных, предоставленную демонстрационной версией блога, мы можем войти с именем пользователя demo и паролем demo. Отметим, что эта система блога не обеспечивает функцию управления пользователями. Поэтому пользователь не может изменить свою учетную запись или создать новую через веб-интерфейс. Функцию управления пользователями можно рассматривать как будущее расширение к приложению блога.

Found a typo or you think this page needs improvement?
Edit it on github !