Yii2 расширяем роли

Потребовалось мне добавить пару ролей в проект Yii2. Задача стояла распределить пользователей на несколько групп. Для этих целей можно использовать RBAC, однако это решение в данном случае было слишком избыточно - требовалось что-то гораздо проще. Т.к. такая задача возникает довольно часто, напишу как можно справиться с ней всего парой строчек кода..
Начнем с модели User. Данные в моем случае хранятся в бд, поэтому User унаследован от ActiveRecord и реализует IdentityInterface.
Добавляем в модель (файл app\models\User.php) необходимые роли и метод проверки ролей can:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | class User extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface {     const ROLE_ADMIN = 'root';     const ROLE_USER = 'user';     const ROLE_ATTORNEY = 'attorney'; ..     public function can($role) {         return $this->role == $role;     } } | 
Далее добавляем колонку role в таблицу user, использя для этого либо миграции, либо напрямую редактируя таблицу, в зависимости от этапа разработки.
Теперь, создаем новый фильтр AccessRule (файл app\components\AccessRule.php), который наследуется от базового и переопределяет метод match:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <?php namespace app\components; class AccessRule extends \yii\filters\AccessRule {     /**      * @inheritdoc      */     protected function matchRole($user)     {         if (empty($this->roles)) {             return true;         }         foreach ($this->roles as $role) {             if ($role === '?') {                 if ($user->getIsGuest()) {                     return true;                 }             } elseif ($role === '@') {                 if (!$user->getIsGuest()) {                     return true;                 }             } elseif ($user->can($role)) {                 return true;             } elseif ($identity = $user->getIdentity()) {                 if ($identity->can($role)) {                     return true;                 }             }         }         return false;     } } | 
Здесь мы добавили в конец проверок, вызов метода can из модели User который мы определили ранее.
Вот и всё, теперь нам осталось в соответствующем контроллере, переопределить namespace AccessRule на наш и можно использовать правила фильтрации как и раньше, но уже с нашими ролями:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | namespace app\controllers; use Yii; use yii\filters\AccessControl; use app\components\AccessRule; .. use app\models\User; class SiteController extends Controller {     /**      * @inheritdoc      */     public function behaviors()     {         return [             'access' => [                 'class' => AccessControl::className(),                 'ruleConfig' => [                     'class' => AccessRule::className(),                 ],                 'only' => ['test'],                 'rules' => [                     [                         'actions' => ['test'],                         'allow' => true,                         'roles' => [User::ROLE_ADMIN],                     ],                 ],             ],         ];     } | 
Как видите, задача решается довольно просто. Слава фреймворку Yii 2 и его разработчикам 😀
Author: | Rating: / | Tags:
 
                    
                 
                    
                 
                    
                
14 comments.
Write a comment