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: | Tags: /
| Rating:
14 comments.
Write a comment