Аутентифікація користувача ========================== Наш додаток повинен розрізняти власника системи та гостей. Тому ми повинні реалізувати функцію [користувальницької аутентифікації](/doc/guide/uk/topics.auth). Ви, можливо, помітили, що каркас додатка вже реалізує аутентифікацію, перевіряючи, чи є імʼя користувача та пароль значеннями `demo` та `admin`. У цьому розділі ми змінимо відповідний код так, щоб аутентифікація відбувалася за допомогою таблиці `User` БД. Аутентифікація користувача виконується у класі, який реалізує інтерфейс [IUserIdentity]. Для цієї мети каркас додатка використовує клас `UserIdentity`. Клас знаходиться у файлі `/wwwroot/blog/protected/components/UserIdentity.php`. > Tip|Підказка: У відповідності з угодою, назва файла класу має бути > такою ж, як імʼя класу плюс розширення `.php`. Можна звернутися до класу, використовуючи > [псевдонім шляху](/doc/guide/uk/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/uk/database.ar) для того, щоб звертатися до таблиці `tbl_user` в ОО манері. Для того, щоб перевірити чи ввів користувач правильний пароль, ми викликаємо метод `validatePassword` класу `User`. Нам необхідно змінити файл `/wwwroot/blog/protected/models/User.php` як показано нижче. Відзначимо, що замість зберігання пароля у БД у явному вигляді, ми зберігаємо його хеш. При перевірці введеного користувачем пароля, замість порівняння паролів, ми повинні порівнювати хеші. Для хешування пароля і його перевірки ми використовуємо клас [CPasswordHelper], що входить до Yii. ~~~ [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`. Відзначимо, що ця система блогу не забезпечує функцію управління користувачами. Тому користувач не може змінити свій обліковий запис або створити новий через веб-інтерфейс. Функцію управління користувачами можна розглядати як майбутнє розширення до додатка блогу.