- Общие вопросы
- Установка и настройка
- Модели
- Формы
- Краткий справочник по валидации
- Свои сообщения для ошибок валидации
- Использование собственных фильтров в правилах валидации
- Как загрузить файл используя модель
- Как загрузить файл используя модель (вариант с толстой моделью)
- Добавляем CAPTCHA к форме
- Как подключить FCKeditor
- Вывод CStarRating в GridView
- Расширяем CFormatter
- Использование виджета CMaskedTextField
- Контроль доступа
- JavaScript
- Особенности фреймворка
RBAC и описание ролей в файле
В официальном руководстве загрузка правил для RBAC из файла практически не разбирается. Восполним этот недостаток.
Поставим задачу. Необходимо определить четыре роли: guest, user, moderator,
administrator и назначить их пользователям из базы данных с соответствующим
полем role. Затем проверить доступ.
Первым делом настроим сам компонент. protected/config/main.php:
'authManager' => array( // Будем использовать свой менеджер авторизации 'class' => 'PhpAuthManager', // Роль по умолчанию. Все, кто не админы, модераторы и юзеры — гости. 'defaultRoles' => array('guest'), ),
Опишем protected/config/auth.php:
return array( 'guest' => array( 'type' => CAuthItem::TYPE_ROLE, 'description' => 'Guest', 'bizRule' => null, 'data' => null ), 'user' => array( 'type' => CAuthItem::TYPE_ROLE, 'description' => 'User', 'children' => array( 'guest', // унаследуемся от гостя ), 'bizRule' => null, 'data' => null ), 'moderator' => array( 'type' => CAuthItem::TYPE_ROLE, 'description' => 'Moderator', 'children' => array( 'user', // позволим модератору всё, что позволено пользователю ), 'bizRule' => null, 'data' => null ), 'administrator' => array( 'type' => CAuthItem::TYPE_ROLE, 'description' => 'Administrator', 'children' => array( 'moderator', // позволим админу всё, что позволено модератору ), 'bizRule' => null, 'data' => null ), );
Сделаем, чтобы Yii::app()->user->id возвращала id пользователя. Для этого немного
изменим класс UserIdentity. protected/components/UserIdentity.php:
class UserIdentity extends CUserIdentity { // Будем хранить id. protected $_id; // Данный метод вызывается один раз при аутентификации пользователя. public function authenticate(){ // Производим стандартную аутентификацию, описанную в руководстве. $user = User::model()->find('LOWER(login)=?', array(strtolower($this->username))); if(($user===null) || (md5($this->password)!==$user->password)) { $this->errorCode = self::ERROR_USERNAME_INVALID; } else { // В качестве идентификатора будем использовать id, а не username, // как это определено по умолчанию. Обязательно нужно переопределить // метод getId(см. ниже). $this->_id = $user->id; // Далее логин нам не понадобится, зато имя может пригодится // в самом приложении. Используется как Yii::app()->user->name. // realName есть в нашей модели. У вас это может быть name, firstName // или что-либо ещё. $this->username = $user->realName; $this->errorCode = self::ERROR_NONE; } return !$this->errorCode; } public function getId(){ return $this->_id; } }
Далее реализуем получение роли из БД при использовании Yii::app()->user->role.
Для этого расширим CWebUser. protected/components/WebUser.php:
class WebUser extends CWebUser { private $_model = null; function getRole() { if($user = $this->getModel()){ // в таблице User есть поле role return $user->role; } } private function getModel(){ if (!$this->isGuest && $this->_model === null){ $this->_model = User::model()->findByPk($this->id, array('select' => 'role')); } return $this->_model; } }
Чтобы приложение использовало наш класс WebUser, необходимо сконфигурировать
компонент user:
'user'=>array( 'class' => 'WebUser', // … ),
Подсказка: Точно таким же способом можно переопределить любой компонент Yii.
Теперь у нас есть набор ролей и мы знаем роль пользователя. Осталось связать их.
Для этого создадим класс PhpAuthManager. protected/components/PhpAuthManager.php:
class PhpAuthManager extends CPhpAuthManager{ public function init(){ // Иерархию ролей расположим в файле auth.php в директории config приложения if($this->authFile===null){ $this->authFile=Yii::getPathOfAlias('application.config.auth').'.php'; } parent::init(); // Для гостей у нас и так роль по умолчанию guest. if(!Yii::app()->user->isGuest){ // Связываем роль, заданную в БД с идентификатором пользователя, // возвращаемым UserIdentity.getId(). $this->assign(Yii::app()->user->role, Yii::app()->user->id); } } }
Теперь можно пользоваться:
if(Yii::app()->user->checkAccess('administrator')){ echo "hello, I'm administrator"; }
Также можно проверять права в методе accessRules, как показано в руководстве.
Подсказка: не обязательно создавать
auth.phpвручную, можно воспользоваться методами CAuthManager (Yii::app()->authManager), описанными в руководстве. Не забудьте вызватьYii::app()->authManager->save().
Приложение 1: модель User:
/** * Модель User * * @property integer $id * @property string $login * @property string $password * @property string $role */ class User extends CActiveRecord { const ROLE_ADMIN = 'administrator'; const ROLE_MODER = 'moderator'; const ROLE_USER = 'user'; const ROLE_BANNED = 'banned'; public static function model($className=__CLASS__){ return parent::model($className); } public function tableName(){ return 'User'; } protected function beforeSave(){ $this->password = md5($this->password); return parent::beforeSave(); } }
Автор: Александр Макаров, Sam Dark (rmcreative.ru)Дополнения: EkstaziОбсуждение и комментарии: http://yiiframework.ru/forum/viewtopic.php?f=8&t=156
