
Наш додаток повинен розрізняти власника системи та гостей. Тому ми повинні реалізувати функцію користувальницької аутентифікації.
Ви, можливо, помітили, що каркас додатка вже реалізує аутентифікацію,
перевіряючи, чи є імʼя користувача та пароль значеннями demo та admin.
У цьому розділі ми змінимо відповідний код так, щоб аутентифікація
відбувалася за допомогою таблиці User БД.
Аутентифікація користувача виконується у класі, який реалізує інтерфейс
IUserIdentity. Для цієї мети каркас додатка використовує клас UserIdentity.
Клас знаходиться у файлі /wwwroot/blog/protected/components/UserIdentity.php.
Підказка: У відповідності з угодою, назва файла класу має бути
.php. Можна звернутися до класу, використовуючи псевдонім шляху. Наприклад, ми можемо звернутися до класуUserIdentityвикористовуючи псевдонімapplication.components.UserIdentity. Багато методів API у Yii можуть розпізнати псевдоніми шляху (наприклад, Yii::createComponent()). Це дозволяє уникнути використання абсолютних шляхів у коді, які створюють неприємності при розгортанні додатка.
Модифікуємо клас UserIdentity наступним чином:
php<?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 як показано нижче.
Відзначимо, що замість зберігання пароля у БД у явному вигляді, ми зберігаємо його хеш.
При перевірці введеного користувачем пароля, замість порівняння паролів, ми повинні порівнювати хеші.
Для хешування пароля і його перевірки ми використовуємо клас CPasswordHelper, що входить до Yii.
phpclass 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_pathPHP в конфігурації додатка наступним чином:[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; … }
Інформація: Люди часто плутаються в ідентифікації (identity) та компоненті
user. Перша представляє спосіб виконання аутентифікації, у той час як останній використовується, щоб надати інформацію, повʼязану з поточним користувачем. У додатка може бути тільки один компонентuser, але один або кілька класів ідентифікації, в залежності від того, яку аутентифікацію підтримує додаток. При аутентифікації, екземпляр ідентифікації може передати деяку інформацію компонентуuser. Ця інформація буде глобально доступна через компонентuser.
Щоб перевірити змінений клас UserIdentity, ми можемо відкрити адресу
http://www.example.com/blog/index.php і спробувати увійти з імʼям
користувача та паролем, які ми зберігаємо у таблиці tbl_user.
Якщо ми використовуємо базу даних, надану
демонстраційною версією блогу,
ми можемо увійти з імʼям користувача demo і паролем demo.
Відзначимо, що ця система блогу не забезпечує функцію управління користувачами.
Тому користувач не може змінити свій обліковий запис або створити новий через веб-інтерфейс.
Функцію управління користувачами можна розглядати як майбутнє розширення до додатка блогу.
<?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;
}
}