Аутентификация пользователя =========================== Наше приложение должно различать владельца системы и гостей. Поэтому мы должны реализовать функцию [пользовательской аутентификации](/doc/guide/ru/topics.auth). Вы, возможно, заметили, что каркас приложения уже реализует аутентификацию, проверяя, являются ли имя пользователя и пароль значениями `demo` и `admin`. В этом разделе мы изменим соответствующий код так, чтобы аутентификация происходила посредством таблицы `User` БД. Аутентификация пользователя выполняется в классе, который реализует интерфейс [IUserIdentity]. Для этой цели каркас приложения использует класс `UserIdentity`. Класс находится в файле `/wwwroot/blog/protected/components/UserIdentity.php`. > Tip|Подсказка: В соответствии с соглашением, название файла класса должно быть > таким же как имя класса плюс расширение `.php`. Можно обратиться к классу, используя > [псевдоним пути](/doc/guide/ru/basics.namespace). Например, мы > можем обратиться к классу `UserIdentity` используя псевдоним > `application.components.UserIdentity`. Многие методы API в Yii могут распознать > псевдонимы пути (например, [Yii::createComponent()|YiiBase::createComponent]). > Это позволяет избежать использования абсолютных путей в коде, которые создают > неприятности при развертывании приложения. Модифицируем класс `UserIdentity` следующим образом: ~~~ [php] 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](/doc/guide/ru/database.ar) для того, чтобы обращаться к таблице `tbl_user` в ОО манере. Для того, чтобы проверить, ввёл ли пользователь правильный пароль, мы вызываем метод `validatePassword` класса `User`. Нам необходимо изменить файл `/wwwroot/blog/protected/models/User.php` как показано ниже. Отметим, что вместо хранения пароля в БД в явном виде, мы сохраняем его хеш. При проверке введённого пользователем пароля, вместо сравнения паролей, мы должны сравнивать хеши. Для хеширования пароля и его проверки мы используем входящий в Yii класс [CPasswordHelper]. ~~~ [php] 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` в любом месте нашего кода. > Tip|Подсказка: В классе `UserIdentity` мы используем [CUserIdentity] > без явного подключения соответствующего файла. Это возможно т.к. > [CUserIdentity] — один из классов ядра фреймворка Yii. Yii будет > автоматически подключать файл класса для любого класса ядра, когда к нему > обратятся впервые. То же возможно с классом `User` т.к. он расположен в директории > `/wwwroot/blog/protected/models`, которая была добавлена к параметру > `include_path` PHP в конфигурации приложения следующим образом: > > ~~~ > [php] > return array( > … > 'import'=>array( > 'application.models.*', > 'application.components.*', > ), > … > ); > ~~~ > > Конфигурация выше говорит, что любой класс, файл которого расположен > в директории `/wwwroot/blog/protected/models` или > `/wwwroot/blog/protected/components`, будет автоматически подключен, когда к > классу обратятся впервые. Класс `UserIdentity` используется классом `LoginForm` для аутентификации пользователя, основанной на введенных имени и пароле, полученных на странице входа в систему. Следующий фрагмент кода показывает как используется класс `UserIdentity`: ~~~ [php] $identity=new UserIdentity($username,$password); $identity->authenticate(); switch($identity->errorCode) { case UserIdentity::ERROR_NONE: Yii::app()->user->login($identity); break; … } ~~~ > Info|Информация: Люди часто путаются в идентификации (identity) и компоненте > приложения `user`. Первая представляет способ выполнения аутентификации, в то > время как последний используется, чтобы представить информацию, связанную с > текущим пользователем. У приложения может быть только один компонент `user`, > но один или несколько классов идентификации, в зависимости от того, какую > аутентификацию поддерживает приложение. При аутентификации, > экземпляр идентификации может передать некоторую информацию компоненту `user`. > Эта информация будет глобально доступна через компонент `user`. Чтобы проверить изменённый класс `UserIdentity`, мы можем открыть адрес `http://www.example.com/blog/index.php` и попытаться войти с именем пользователя и паролем, которые мы храним в таблице `tbl_user`. Если мы используем базу данных, предоставленную [демонстрационной версией блога](http://www.yiiframework.com/demos/blog/), мы можем войти с именем пользователя `demo` и паролем `demo`. Отметим, что эта система блога не обеспечивает функцию управления пользователями. Поэтому пользователь не может изменить свою учетную запись или создать новую через веб-интерфейс. Функцию управления пользователями можно рассматривать как будущее расширение к приложению блога.