Когда ваш проект на Yii2 вырастает из песочницы, возникает вопрос: как сделать так, чтобы каждый пользователь видел только то, что ему положено? Базовая аутентификация не справляется, а права "админ-не админ" — это как светофор с двумя цветами. Тут на сцену выходит RBAC (Role-Based Access Control) — управление доступом на основе ролей. В этой статье я покажу, как построить расширенную систему RBAC, которая не сломается, когда у вас появится сто ролей и тысяча разрешений.
Что такое RBAC и зачем он нужен
RBAC — это как гардеробная в театре: у каждого актёра есть свой костюм (роль), и он может заходить только в те комнаты, которые соответствуют его костюму. В Yii2 это реализовано через иерархию ролей, разрешений и правил. Простыми словами: роль — это группа прав, а разрешение — конкретное действие (например, "редактировать статью"). Правила — это дополнительные фильтры, которые проверяют, может ли пользователь выполнить действие в данный момент.
Зачем это нужно? Чтобы не писать сотни if-else по всему коду. Чтобы можно было быстро добавить нового модератора, не переписывая логику. Чтобы безопасность была на уровне, а не на честном слове.
Настройка компонента authManager
Первым делом нужно включить RBAC в Yii2. Откройте файл конфигурации (обычно config/web.php или config/main.php) и добавьте компонент authManager. Выберите способ хранения: файловый (простой, но не для продакшена) или база данных (рекомендую). Вот пример настройки для БД:
'components' => [
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
],После этого выполните миграцию для создания таблиц RBAC. В Yii2 есть встроенная миграция. Запустите в консоли:
yii migrate --migrationPath=@yii/rbac/migrationsЭта команда создаст четыре таблицы: auth_item (роли и разрешения), auth_item_child (связи между ними), auth_assignment (назначение ролей пользователям) и auth_rule (правила). Теперь фундамент готов.
Создание ролей и разрешений: первый этап
Теперь нужно наполнить систему. Обычно это делается в консольной команде или миграции. Создадим базовые роли: user, moderator, admin. И разрешения: createPost, updatePost, deletePost.
$auth = Yii::$app->authManager;
// Создаем роли
$user = $auth->createRole('user');
$moderator = $auth->createRole('moderator');
$admin = $auth->createRole('admin');
// Создаем разрешения
$createPost = $auth->createPermission('createPost');
$updatePost = $auth->createPermission('updatePost');
$deletePost = $auth->createPermission('deletePost');
// Добавляем в систему
$auth->add($user);
$auth->add($moderator);
$auth->add($admin);
$auth->add($createPost);
$auth->add($updatePost);
$auth->add($deletePost);
// Назначаем разрешения ролям
$auth->addChild($user, $createPost);
$auth->addChild($moderator, $updatePost);
$auth->addChild($admin, $deletePost);
$auth->addChild($admin, $moderator); // admin наследует права moderator
$auth->addChild($moderator, $user); // moderator наследует права userОбратите внимание: addChild создаёт иерархию. Админ получает все права модератора и пользователя. Это мощный механизм, но будьте осторожны: случайное наследование может открыть доступ туда, где не нужно.
Расширенные возможности: правила и бизнес-логика
Просто ролей и разрешений часто мало. Например, пользователь может редактировать только свои посты. Тут в игру вступают правила (rules). Правило — это класс, который реализует интерфейс yii\rbac\Rule. Он проверяет, можно ли выполнить действие в контексте.
class AuthorRule extends \yii\rbac\Rule
{
public $name = 'isAuthor';
public function execute($user, $item, $params)
{
return isset($params['post']) ? $params['post']->created_by == $user : false;
}
}Теперь привяжем правило к разрешению updateOwnPost:
$auth = Yii::$app->authManager;
$rule = new AuthorRule();
$auth->add($rule);
$updateOwnPost = $auth->createPermission('updateOwnPost');
$updateOwnPost->ruleName = $rule->name;
$auth->add($updateOwnPost);
// Назначаем пользователю
$auth->addChild($user, $updateOwnPost);Правила можно комбинировать. Например, правило "isAuthor" плюс разрешение "updatePost" дадут возможность редактировать только свои посты, а не чужие. Это как ключ от квартиры: он подходит только к вашей двери.
Проверка прав в контроллерах и представлениях
Когда система настроена, нужно её использовать. Самый простой способ — через Yii::$app->user->can(). В контроллере это выглядит так:
public function actionUpdate($id)
{
$post = Post::findOne($id);
if (!Yii::$app->user->can('updatePost', ['post' => $post])) {
throw new \yii\web\ForbiddenHttpException('Доступ запрещен');
}
// логика обновления
}В представлениях можно скрывать кнопки:
if (Yii::$app->user->can('updatePost', ['post' => $model])) {
echo Html::a('Редактировать', ['update', 'id' => $model->id]);
}Для глобальной проверки используйте фильтры доступа (AccessControl) в поведении контроллера:
public function behaviors()
{
return [
'access' => [
'class' => \yii\filters\AccessControl::class,
'rules' => [
[
'allow' => true,
'roles' => ['@'], // только авторизованные
],
[
'allow' => true,
'actions' => ['create'],
'permissions' => ['createPost'], // проверка разрешения
],
],
],
];
}Yii::$app->user->identity->role == 'admin'). Это убивает гибкость. Всегда используйте разрешения. Тогда, если завтра роль админа переименуют, ваш код не сломается.Таблица сравнения способов хранения
| Способ | Плюсы | Минусы |
|---|---|---|
| PhpManager (файлы) | Простота, не требует БД | Не подходит для продакшена, нет миграций |
| DbManager (БД) | Гибкость, поддержка миграций, масштабирование | Требует настройки БД |
Я всегда выбираю DbManager. Даже для мелких проектов — привычка, которая спасает, когда проект внезапно становится большим.
Советы по расширению системы
- Группируйте разрешения. Создайте промежуточные роли, например,
editor(редактор контента) иmanager(управление пользователями). Это упростит иерархию. - Используйте кэширование. RBAC-запросы могут быть частыми. Включите кэш для
authManagerв конфиге: добавьте свойствоcacheс компонентом кэша. - Не злоупотребляйте правилами. Сложные правила замедляют систему. Если правило проверяет что-то тяжёлое (например, запрос к внешнему API), подумайте о кэшировании результата.
- Документируйте роли. Когда ролей станет много, без документации вы запутаетесь. Ведите список в комментариях к миграциям.
Что в итоге
RBAC в Yii2 — это не rocket science. Вы настроили компонент, создали роли и разрешения, добавили правила для бизнес-логики и теперь проверяете права в контроллерах. Система стала гибкой: вы можете добавить новую роль за пять минут, не трогая код. Главное — не ленитесь и не используйте хардкод. Помните: хорошая система прав — это как хороший фундамент: его не видно, но на нём всё держится.
Студия WNDER

