Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Роли и разрешения (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 — и доступ закрыт всем, включая администратора. Проверьте, что компонент добавлен в оба файла настроек и что роль действительно назначена пользователю.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.