Роли и разрешения (RBAC)
Когда пользователей с разными правами становится несколько — автор, редактор, администратор, — проверок isGuest уже мало. RBAC (управление доступом на основе ролей) описывает права двумя понятиями: разрешение — отдельное действие вроде «изменить статью», роль — набор разрешений, который назначают пользователю.
Подключение
За RBAC отвечает компонент authManager. Добавьте его в config/web.php и в config/console.php:
// config/web.php и config/console.php
'components' => [
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
],DbManager хранит роли в базе данных. Таблицы для него создаёт готовая миграция:
php yii migrate --migrationPath=@yii/rbac/migrationsВ базе появятся четыре таблицы с именами, начинающимися на auth_.
Создание ролей и разрешений
Роли создают один раз — консольной командой. Создайте файл commands/RbacController.php:
// commands/RbacController.php
namespace app\commands;
use Yii;
use yii\console\Controller;
class RbacController extends Controller
{
public function actionInit(): void
{
$auth = Yii::$app->authManager;
$auth->removeAll();
$createPost = $auth->createPermission('createPost');
$auth->add($createPost);
$deletePost = $auth->createPermission('deletePost');
$auth->add($deletePost);
$author = $auth->createRole('author');
$auth->add($author);
$auth->addChild($author, $createPost);
$admin = $auth->createRole('admin');
$auth->add($admin);
$auth->addChild($admin, $author);
$auth->addChild($admin, $deletePost);
}
}php yii rbac/initКоманда записывает в базу два разрешения и две роли. addChild() вкладывает одно в другое: автор может создавать статьи, а администратор получает всё, что может автор, и ещё удаление.
Назначение роли пользователю
$auth = Yii::$app->authManager;
$auth->assign($auth->getRole('author'), $user->id);Вызов связывает роль с номером пользователя. Его удобно делать сразу после регистрации. Отнять роль — $auth->revoke($role, $user->id).
Проверка в коде
public function actionDelete(int $id)
{
if (!Yii::$app->user->can('deletePost')) {
throw new ForbiddenHttpException('Удалять статьи может только администратор.');
}
// удаление
}Метод can() возвращает true, если у текущего пользователя есть разрешение — напрямую или через роль. Автор получит ошибку 403, администратор удалит статью. Проверяйте разрешения, а не роли: тогда состав ролей можно менять, не трогая код.
Проверка в фильтре
AccessControl понимает имена ролей и разрешений в ключе roles:
'rules' => [
[
'allow' => true,
'actions' => ['create'],
'roles' => ['createPost'],
],
[
'allow' => true,
'actions' => ['delete'],
'roles' => ['deletePost'],
],
],Фильтр вызывает can() сам, поэтому проверку в действии можно не повторять.
Проверка в шаблоне
<?php
// views/post/view.php
use yii\helpers\Html;
?>
<?php if (Yii::$app->user->can('deletePost')): ?>
<?= Html::a('Удалить', ['post/delete', 'id' => $post->id], ['data-method' => 'post']) ?>
<?php endif; ?>Кнопку удаления увидит только администратор.
Частая ошибка
Если компонент authManager не описан в настройках, can() не выдаёт ошибку, а просто возвращает false — и доступ закрыт всем, включая администратора. Проверьте, что компонент добавлен в оба файла настроек и что роль действительно назначена пользователю.