RBAC в Yii2
суббота, 6 декабря 2014 09:04:43, написал Admin
Наконец-то я вернулся к любимому Yii. И сразу пришлось обкатывать вторую версию. О новшествах и отличиях расскажу в другой раз. Цель этой статьи – познакомится с организацией доступа по ролям пользователей в Yii2 (RBAC).
Роли пользователей будем хранить в базе данных. Для реализации задачи возьмем стандартный модуль rbac, поставляемый по молчанию в Yii2.
Установка
Сначала настроим конфиг. В компонентах пропишем
'components' => [ 'authManager' => [ 'class' => 'yii\rbac\DbManager', 'defaultRoles' => [ 'user', 'moderator', 'admin', 'superadmin' ], ], 'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => true, ], … ]
У нас есть четыре роли. В модели User добавляем строковое поле role.
Создаем таблицы правил ролей. Можно через миграции, но я сразу выполнил импорт в базу данных файла
\vendor\yiisoft\yii2\rbac\migrations\schema-mysql.sql
Пишем класс правила для ролей:
namespace app\components\rbac; use Yii; use yii\rbac\Rule; /** * User group rule class. */ class GroupRule extends Rule { /** * @inheritdoc */ public $name = 'group'; /** * @inheritdoc */ public function execute($user, $item, $params) { if (!Yii::$app->user->isGuest) { $role = Yii::$app->user->identity->role; if ($item->name === 'superadmin') { return $role === $item->name; } elseif ($item->name === 'admin') { return $role === $item->name || $role === 'superadmin'; } elseif ($item->name === 'moderator ') { return $role === $item->name || $role === 'superadmin' || $role === 'admin'; } elseif ($item->name === 'user') { return $role === $item->name || $role === 'superadmin' || $role === 'admin' || $role === 'moderator'; } } return false; } }
Пишем класс консольной команды для занесения ролей в базу данных
namespace app\commands; use Yii; use yii\console\Controller; use app\components\rbac\GroupRule; use yii\rbac\DbManager; /** * RBAC console controller. */ class RbacController extends Controller { /** * Initial RBAC action * @param integer $id Superadmin ID */ public function actionInit($id = null) { $auth = new DbManager; $auth->init(); $auth->removeAll(); //удаляем старые данные // Rules $groupRule = new GroupRule(); $auth->add($groupRule); // Roles $user = $auth->createRole('user'); $user->description = 'User'; $user->ruleName = $groupRule->name; $auth->add($user); $moderator = $auth->createRole(' moderator '); $moderator ->description = 'Moderator '; $moderator ->ruleName = $groupRule->name; $auth->add($moderator); $auth->addChild($moderator, $user); $admin = $auth->createRole('admin'); $admin->description = 'Admin'; $admin->ruleName = $groupRule->name; $auth->add($admin); $auth->addChild($admin, $moderator); $superadmin = $auth->createRole('superadmin'); $superadmin->description = 'Superadmin'; $superadmin->ruleName = $groupRule->name; $auth->add($superadmin); $auth->addChild($superadmin, $admin); // Superadmin assignments if ($id !== null) { $auth->assign($superadmin, $id); } } }
Выполняем команду
php yii rbac/init
Если хотим просто добавить роли или
php yii rbac/init 1
- если хотим привязать роль супердамина пользователю с id=1 И наконец в модели пользователей, после добавления или обновления присваиваем роль:
public function afterSave($insert, $changedAttributes) { parent::afterSave($insert, $changedAttributes); // установка роли пользователя $auth = Yii::$app->authManager; $name = $this->role ? $this->role : self::ROLE_USER; $role = $auth->getRole($name); if (!$insert) { $auth->revokeAll($this->id); } $auth->assign($role, $this->id); }
Использование
В контролере пишем
public function behaviors() { return [ 'access' => [ 'class' => AccessControl::className(), 'rules' => [ [ 'allow' => true, 'actions'=>['index','view'], 'roles' => ['@'], ], [ 'allow' => true, 'roles' => ['admin'], ], ], ], ]; }
Мы разрешили просматривать всем зарегистрированным пользователям 'index' и 'view', остальные экшены доступны только админам.
В любом месте приложения можно вызывать
If (Yii::$app->user->can('admin')) { … }
Для проверки роли пользователя.
На этом все.