
Например можно создать такие роли:
- user
- manager
- admin
Первая роль user - это простой пользователь, который, например, не может ничего делать на сайте кроме как читать статьи и оставлять комментарии. При наличии панели администратора (backend) у него нет доступа к backend\controllers.
Для роли manager, например, мы разрешаем создавать новые статьи, выполнять любые действия с ними, проверять и активировать комментарии пользователей в админке и тд.
Роль admin, разумеется, имеет полные права и может делать все что и manager, плюс, например, создавать в админке новых пользователей, наделять их правами и тд.
По аналогии можно создать еще несколько ролей, если требуется, и просто определиться с правами которые у них будут, т.е. к чему именно у них будет доступ. Возможно при создании примитивного RBAC о чем пойдет речь ниже меньше гибкости но огромный плюс - простота.
В таблицу user (или users) нужно добавить поле role с числовыми идентификаторами обозначающими роль (будут прописаны в сущности (модели) User). Создаем миграцию и вставляем в нее такие методы для изменения таблицы user:
class m190226_182929_add_users_role_field extends Migration { /** * {@inheritdoc} */ public function safeUp() { $this->addColumn('{{%user}}', 'role', $this->smallInteger()->after('email')->defaultValue(1)); } /** * {@inheritdoc} */ public function safeDown() { $this->dropColumn('{{%user}}', 'role'); } }По-умолчанию выставляется 1. Сделаем, чтобы это была роль пользователя.
В примере я буду создавать 3 роли:
user
manager
admin
Добавляем в сущность User (обычно находится в common\models или в app\models) такие константы:
const ROLE_USER = 1; const ROLE_MODER = 5; const ROLE_ADMIN = 10;
Ниже добавим нужные методы для работы:
public static function roles() { return [ self::ROLE_USER => Yii::t('app', 'User'), self::ROLE_ADMIN => Yii::t('app', 'Admin'), self::ROLE_MANAGER => Yii::t('app', 'Manager'), ]; } /** * Название роли * @param int $id * @return mixed|null */ public function getRoleName(int $id) { $list = self::roles(); return $list[$id] ?? null; } public function isAdmin() { return ($this->role == self::ROLE_ADMIN); } public function isManager() { return ($this->role == self::ROLE_MANAGER); } public function isUser() { return ($this->role == self::ROLE_USER); }
Для своего пользователя (администратора) не забыть поставить в БД роль админа (в данном примере цифру 10 в поле role). Можно прямо в миграции прописать такой запрос к БД.
Вот и все. Пример использования в любом нужном контроллере:
public function behaviors() { return [ 'access' => [ 'class' => AccessControl::class, 'rules' => [ [ 'allow' => false, 'roles' => ['?'], 'denyCallback' => function($rule, $action) { return $this->redirect(Url::toRoute(['/site/login'])); } ], [ 'actions' => [], 'allow' => true, 'roles' => ['@'], 'matchCallback' => function ($rule, $action) { /** @var User $user */ $user = Yii::$app->user->getIdentity(); return $user->isAdmin() || $user->isManager(); } ], ], ], ]; }
Для незарегистрированных пользователей при переходе на этот контроллер произойдет перенаправление на страницу авторизации '/site/login', а для ролей не соответствующих роли менеджера и админа будет выброшено исключение ForbiddenHttpException с кодом 403.
Так же можно делать проверку на соответствие роли в любом нужном методе:
if (!Yii::$app->user->getIdentity()->isAdmin()){ throw new HttpException(403, Yii::t('app', 'You are not allowed to perform this action.')); }или так:
/** @var $user User */ $user = Yii::$app->user->getIdentity(); if (!$user || !in_array($user->role, [User::ROLE_ADMIN, User::ROLE_MANAGER])) { throw new HttpException(403, Yii::t('app', 'You are not allowed to perform this action.')); }
Закрыть админку сайта от неавторизованных пользователей очень удобно в конфигурационном файле, чтобы не писать лишний код в каждом backend контроллере.
backend\config\main.php:
return [ 'id' => 'app-backend', 'basePath' => dirname(__DIR__), 'controllerNamespace' => 'backend\controllers', 'bootstrap' => ['log'], 'modules' => [], 'as access' => [ 'class' => 'yii\filters\AccessControl', 'except' => ['site/login', 'site/error'], 'rules' => [ [ 'allow' => true, 'roles' => ['@'], ], ], ], ...Таким образом доступ закрыт для всех пользователей которые не авторизовались ко всем действиям в backend (кроме 'login' и 'error').
Вот так можно создать очень простой RBAC за пару минут и тем не менее часто большего и не нужно.