Yii2 RBAC DbManager - часть 2. Роли, разрешения и правила доступа.
  • 125

Yii2 RBAC DbManager - часть 2. Роли, разрешения и правила доступа.

Автор: admin | 24 октября (Чт.) 2019г. в 21ч.42м.

Вступление.

Эта вторая статья из цикла статей про работу со встроенным в yii2 компонентом RBAC. В данной статье я продолжу знакомить читателя с приемами программирования с rbac на основе базы данных.

Ссылка на первую часть тут

Краткое содержание урока.

Таблицы в базе данных.Что тут к чему...

В первой части мы рассмотрели создание таблиц для rbac с помощью миграций. Для того, чтобы далее понимать как работает rbac нужно разобраться, какие таблицы для чего нужны и что в них хранится. 
RBAC DbManager использует четыре таблицы - auth_assignmentauth_item , auth_item_child , auth_rule
 
auth_assignment - таблица, которая служит для связи user id и его роли (или ролей). Id пользователя соответствует id из таблицы user. Таблица состоит из трех полей. Именно эта таблица служит для определения роли пользователя по его id:

  • item_name - название роли
  • user_id - id юзера из соответствующее id таблицы user
  • created_at - дата присвоения роли пользователю

auth_item
 - данная таблица нужна для хранения созданных имен ролей и разрешений. Эти имена и используются в таблице auth_assignment в поле item_name.
Состоит из таких полей:

  • name - имя роли или разрешения
  • type - если 1 - то это роль, 2 - разрешение
  • description - описание роли или разрешения
  • rule_name - имя правила, применяемое к данному разрешению или роли
  • data - дополнительные данные хранятся в сериализованном виде.
  • created_at -дата создания
  • updated_at - дата обновления записи

Как видно и роли и разрешения хранятся в одной таблице и различия между ними только в значении type (1 или 2). По сути данные два понятия как роль и разрешение нужны лишь для того, чтобы как-то структурировать управление rbac. И тут нет четких законов как надо делать. Таблицы базы у нас в распоряжении и мы вольны делать с ними все, что угодно. Но все же если разработчики создали данное расширение, будем придерживаться выбранной линии и делать все в рамках api rbac.

auth_item_child - данная таблица содержит значения, оприделяющие какие роли и разрешения являются дочерними, а какие родительскими.Содержит всего два поля:

  • parent - имя родительского разрешения или роли 
  • child  - имя дочернего разрешения или роли 

Имена разрешений и ролей указываются те, что указаны в таблице auth_item.

auth_rule - таблица содержит правила для применения ролей и разрешений. Состоит из четырех полей:

  • name - имя правила
  • data - сериализованный объект yii\rbac\Rule
  • created_at - дата создания записи 
  • updated_at - дата обновления записи

Что такое правила и для чего они нужны, если есть роли? Правила нужны для дополнительной проверки применения роли или разрешения к текущему пользователю. Об этом подробнее далее ...

Роли, разрешения и правила доступа.

RBAC оперирует тремя основными понятиями - роли, разрешения и правила.

Итак, мы определили что роли и разрешения - это фактически одно и тоже (в базе данных), различия лишь в значениях поля type (1 или 2). 

Правила же нужны для дополнительной проверки применения какой-то роли или разрешения к текущему зарегестрированному пользователю. Так, по принадлежности пользователя к роли можно проверить так:
if(Yii::$app->user->can('author')){
//Что-то делаем тут, что относится только к пользователю с ролью автора
}​
В данном случае правило не использовалось. Теперь представте, что нужно решить кто может редактировать посты в блоге. Очевидно, что свои посты в блоге должны иметь возможность редактировать только те авторы, которые написали данные посты. Теперь становится ясно, что просто проверить принадлежность пользователя к роли не достаточно. Нужно еще узнать, является ли он автором именно этого поста.  Для этого и служат правила при проверке роли.

Правило в RBAC Yii2 - это дополнительный параметр проверки прав доступа текущего пользователя.

Таким образом для организации иерархии RBAC на мой взгля лучше придерживаться данной схемы (роль - разрешение - правило).

Например для роли автора author нужно подготовить необходимые разрешения и для каждого разрешения уже назначить правило (если необходимо).
-Author
   -perm_create-post
   -perm_update-post
          -rule_update-post
   -perm_delete_post
          -rule_delete-post​

Разберемся как создавать роли и разрешения. Данный код далее разместим в контроллере, а пока разберемся с api RBAC:

//Сначала сохраним authManager в переменную, чтобы код был короче
$auth = Yii::$app->authManager;

//----------------- Создание роли

//Создадим роль 'author'
$author = $auth->createRole('author');

//Не обязательно, но можно добавить описание роли
$author->description = 'Роль автора';

//Сохраняем роль в базе данных
$auth->add($author);

//-------------------Создание разрешения для создания поста

$permCreatePost = $auth->createPermission('perm_create-post');//создали объект
$permCreatePost->description = 'Разрешение для создания поста';//добавили описание
$auth->add($permCreatePost);//создали запись в базе данных

//-------------------Привяжем разрешение к роли
//Роль - это родительский элемент. Разрешение дочерний элемент роли
$auth->addChild($author, $permCreatePost);


//-------------------Роль и разрешение созданы. Посмотрим как этим пользоваться.

//Для начала назначим какому-то обстрактному пользователю с id=10 роль 'автор'
$auth->assign($author, 10);

//Проверим разрешение и если оно есть, позволим создать пост в блоге
//Так как разрешение 'perm_create-post' ранее было присоеденино к роли 'author',то 
//пользователь с id=10 сможет создать пост
if(\Yii::$app->user->can('perm_create-post')){
   //Выводим форму для создания поста блога
}

//Сделаем то же самое, но через метод authManager напрямую
$userId = \Yii::$app->getUser();
if(\Yii::$app->authManager->checkAccess($userId, 'perm_create-post', $params = [])){
   //Выводим форму для создания поста блога
}

Обратите внимание на методы проверки ролей или разрешений у пользователя. \Yii::$app->user->can('perm_create-post') проверяет разрешение у текущего пользователя, а  \Yii::$app->authManager->checkAccess($userId, 'perm_create-post', $params = [])  позволяет указать в первом параметре id пользователя, для которого нужно проверить возможность доступа. Этот вариант может быть полезен, когда нужно еще больше ограничить доступ и указать например id пользователей, для которых может быть доступ, если у них есть еще и необходимые разрешения:

$auth = \Yii::$app->authManager;

$idUser-1 = 10;
$idUser-2 = 20;
$idUser-3 = 30;

if(
$auth->checkAccess($idUser-1, 'perm_create-post') ||
$auth->checkAccess($idUser-2, 'perm_create-post') ||
$auth->checkAccess($idUser-3, 'perm_create-post')

){
   //Выводим форму для создания поста блога
}

Однако, такой вариант заставляет нас дублировать код $auth->checkAccess($idUser-1, 'perm_create-post') в условии. Тем более, что так можно указать проверку для нескольких пользователей. А что, если таких пользователей много? Вот в таком случае и нужно создать правило для нужного разрешения. 

Мы ранее условились, что свой автор может создавать посты, но редактировать и удалять может только свой пост. Тут уже без правил не обойтись Создадим новые разрешения для роли author и назначим им правила, в которых будем проверять, является ли текущий пользователь автором данной статьи.

Создадим классы правил. Да, одно правило - один класс-наследник от  yii\rbac\Rule

namespace components\rbac;

use yii\rbac\Rule;

/**
 * Проверяем authorID на соответствие с пользователем, переданным через параметры
 * Переменную $params мы передаем сюда, когда вызываем \Yii::$app->user->can('role', $param = ['postOwnerId' => 10]);
 */
class UpdatePostRule extends Rule
{
    public $name = 'rule_update-post';

    /**
     * @param string|int $user the user ID.
     * @param Item $item the role or permission that this rule is associated width.
     * @param array $params parameters passed to ManagerInterface::checkAccess().
     * @return bool a value indicating whether the rule permits the role or permission it is associated with.
     */
    public function execute($user, $item, $params)
    {
        return isset($params['postOwnerId']) ? $params['postOwnerId'] == $user : false;
    }
}

Данный класс сохраняем в приложении. Я предпочитаю хранить правила rbac в папке components/rbac/rules Класс правила содержит один метод, в котором и осуществляется проверка. Вернуть нужно true или false. Соответственно если проверка пройдена, то true 

Правило для удаления поста создавать сделаем немного сложнее. Допустим нужно проверить не только, что текущий пользователь создал этот пост, но и является ли он администраторм. Да. Удалять пост разрешим только администраторам сайта. Пока роли администратора мы не создавали, но мы это сделаем далее.

А пока создадим за ранее правило для проверки того, кто может удалять пост:

namespace components\rbac;

use yii\rbac\Rule;

/**
 * Проверяем authorID на соответствие с пользователем, переданным через параметры
 * Переменную $params мы передаем сюда, когда вызываем \Yii::$app->user->can('role', $param = ['postOwnerId' => 10]);
 */
class DeletePostRule extends Rule
{
    public $name = 'rule_delete-post';

    /**
     * @param string|int $user the user ID.
     * @param Item $item the role or permission that this rule is associated width.
     * @param array $params parameters passed to ManagerInterface::checkAccess().
     * @return bool a value indicating whether the rule permits the role or permission it is associated with.
     */
    public function execute($userId, $item, $params)
    {
        $allowedRoleName = 'admin';

        //Проверим присвоена ли роль админа текущему пользователю
        $assignment = \Yii::$app->authManager->getAssignment($allowedRoleName, $userId);
        
        $isAllowed = $assignment !== null ? true : false;
        return isset($params['postOwnerId']) && $isAllowed ? $params['postOwnerId'] == $user : false;
    }
}

Классы правил созданы. Теперь мы можем добавить разрешения и привязать их к ранее созданной роли 'author'. Тут же привяжем правила к разрешениям на обновление и удаление. Это правда все очень просто сделать.

//Сначала сохраним authManager в переменную, чтобы код был короче
$auth = Yii::$app->authManager;


//Роль мы создали ранее и допустим в этом месте приложения нам нужно получить объект роли //'author' для добавления к роли разрешений и правил
//Найдем и получим объект роли по имени роли
$author = $auth->getRole('author');//тут объект роли 'author'

//По ходу урока было решено создать роль админа, который будет присваивать все привелегии автора. Создадим...
//Создадим роль 'admin'
$admin = $auth->createRole('admin');
$admin->description = 'Роль admin';

//Сохраняем роль в базе данных
$auth->add($admin);

//Поставим админа на вершину пищевой цепочки :)
$auth->addChild($admin, $author);//Наследуем все разрешения от автора

//Создадим нужные разрешения
$permUpdatePost = $auth->createPermission('perm_update-post');//создали объект
$permUpdatePost->description = 'Разрешение для обновления поста';//добавили описание

$permDeletePost = $auth->createPermission('perm_delete-post');//создали объект
$permDeletePost->description = 'Разрешение для удаления поста';//добавили описание

//Теперь нужно присоеденить правила для наших разрешений.
//Теперь в ход пойдут те классы правил, что были нами созданы ранее.
$ruleUpdate = new \compoments\rbac\UpdatePostRule;
$auth->add($ruleUpdate);//сохраняем в бд

$ruleDelete = new \compoments\rbac\DeletePostRule;
$auth->add($ruleDelete);//сохраняем в бд


//В базу правила добавили. Настало время привязать их к разрешениям.
//Для этого передаем в объекты разрешений имена правил
$permUpdatePost->ruleName = $ruleUpdate->name;//тут 'rule_update-post'
$permDeletePost->ruleName = $ruleDelete->name;//тут 'rule_delete-post'

//Теперь объекты разрешений готовы для сохранения в базе данных. Сделаем это.
$auth->add($permUpdatePost);
$auth->add($permDeletePost);

//И наконец привяжим разрешения к роли автора
$auth->addChild($author, $permUpdatePost);
$auth->addChild($author, $permDeletePost);

Все готово для полноценной проверки доступа зарегестрированных пользователей к CRUD нашего блога. Проверять будем так:

$userId = \Yii::$app->getUser();
$idOwnerPost = $currentBlogPost->createdBy;// Обьект поста блога

if(\Yii::$app->authManager->checkAccess($userId, 'perm_update-post', $params = [])){
  //Тут пользователь может обновить пост
}

//Для проверки права на удаление нужно передать параметр в объект правила 'postOwnerId'
if(\Yii::$app->authManager->checkAccess(
    $userId, 
    'perm_delete-post', 
    $params = ['postOwnerId' => $idOwnerPost])
){
  //Тут пользователь может удалить пост
}

Таким образом, проверяя разрешения, автоматом проверяются правила для этих разрешений.

Для каждого разрешения можно привязать только один объект правила.

'defaultRoles' - Роли по умолчанию. Как применить и для чего...

В RBAC Yii2 есть также возможность назначать роли по умолчанию. Делается это в конфигурационном файле так:
'components' => [
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
            'defaultRoles' => ['guest'],
        ],

//Или используя анонимную функцию, которая должна вернуть массив
'components' => [
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
            'defaultRoles' => function(){
                 return \Yii::$app->user->isGuest ? ['guest'] : [];
            },
        ],​
Для примера я установил 'guest' как роль по умолчанию. Отличие роли по умолчанию от ролей, которые мы создавали и привязывали к пользователю по id в том, что обычные роли привязываются к пользователю по id так: Yii::$app->authManager->assign($role, $userId) ,а роль по умолчанию присваивается всем посетителям сайта неявно.
defultRoles не привязывается в базе данных к пользователю, но сама роль должна быть создана и записана в базе данных. Когда мы прописываем имя данной роли в массиве defaultRoles, то эта роль может присваеваться всем посетителям.
Соответственно, можно присвоить данную роль даже не зарегистрированному пользователю.
Создадим роль 'guest' в консольном контроллере:
    public function actionDefaultRole()
    {
        $auth = Yii::$app->authManager;
        $guest = $auth->createRole('guest');
        $auth->add($guest);

        $this->stdout('Role: ' . $guest->name . ' is Done!' . PHP_EOL);
    }​
Запустим экшен консольного контроллера RbacController в консоли: php yii rbac/default-role  
Проверяем наличие роли у посетителя как обычно:
if(\Yii::$app->user->can('guest')){
   //Для гостя код тут...
}​

Единственное отличие дефолтной роли от обычной - отсутствие привязки к зарегестрированному пользователю по id.
Но какая польза от такой роли? Можно же узнать, что пользователь - гость и другим способом как  Yii::$app->user->isGuest 

Да. Польза есть в том, что к defultRoles можно также привязывать правила.

Допустим, нам надо, чтобы на 10 посещении для такого гостя появлялось всплывающее окно с предложением зарегестрироваться и получать на почту уведомления о новых материалах. Создадим defaultRole 'guest', и разрешение 'perm-frequent-visitor

И к роли и к разрешению привяжем правила. Структура такая:

Роль 'guest' (правило для опридеоения гостя)
       -разрешение 'perm-frequent-visitor' (правило для оприделения 10-го визита посетителя)

Сначала создадим классы правил. Первое - правило для определения гостя:

<?php
namespace common\components\rbac\rules;

use yii\rbac\Rule;
use yii\web\Cookie;
use Yii;

class GuestRule extends Rule
{
    public $name = 'rule_detect-guest';

    /**
     * @param string|int $user the user ID.
     * @param Item $item the role or permission that this rule is associated width.
     * @param array $params parameters passed to ManagerInterface::checkAccess().
     * @return bool a value indicating whether the rule permits the role or permission it is associated with.
     */
    public function execute($user, $item, $params)
    {
        return Yii::$app->user->getIsGuest();
    }
}

Далее - правило для определения 10-го визита:

<?php
namespace common\components\rbac\rules;

use yii\rbac\Rule;
use yii\web\Cookie;
use Yii;

class FrequentVisitorRule extends Rule
{
    public $name = 'rule_frequent-visitor';
    const COOKIE_NAME = 'count_visit';

    /**
     * @param string|int $user the user ID.
     * @param Item $item the role or permission that this rule is associated width.
     * @param array $params parameters passed to ManagerInterface::checkAccess().
     * @return bool a value indicating whether the rule permits the role or permission it is associated with.
     */
    public function execute($user, $item, $params)
    {
        // $cookies = Yii::$app->request->cookies;
        $cName = isset($params['counter_cookie_name']) ? $params['counter_cookie_name'] : self::COOKIE_NAME;
        //Если имя куки не передано, значит и не назначено в приложении. Или если имя
        //передано, но куки не установлены - сделаем это тут...
        $counter = Yii::$app->request->cookies->getValue($cName, 0);
        $counter += 1;
        Yii::$app->response->cookies->remove($cName);
        Yii::$app->response->cookies->add(new Cookie([
            'name' => $cName,
            'value' => $counter,//eny
            'expire' => time() + 86400 * 365,
        ]));

        if (Yii::$app->request->cookies->has($cName)){
            return $counter == 10 ? true : false;
        }else{
            return false;
        }
    }
}

Теперь в консольном контроллере создадим 'экшены для создания роли 'гостя', разрешения для 'частого посетителя' и привяжем к ним соответствующие правила:

/**
     * Create role 'guest'
     * In console run yii rbac/create-default-role-guest
     *
     * @return void
     */
    public function actionCreateDefaultRoleGuest()
    {
        $auth = Yii::$app->authManager;
        
        $ruleGuestRule = new \common\components\rbac\rules\GuestRule;
        $auth->add($ruleGuestRule);
        
        $guest = $auth->createRole(Rbac::ROLE_GUEST);
        $guest->description = 'Роль для гостя';
        $guest->ruleName = $ruleGuestRule->name;
        $auth->add($guest);

        $this->stdout('Role: ' . Rbac::ROLE_GUEST . ' is Done!' . PHP_EOL);
    }

    /**
     * Create permission
     * In console run yii rbac/create-frequent-visitor-permission
     *
     * @return void
     */
    public function actionCreateFrequentVisitorPermission()
    {
        $auth = Yii::$app->authManager;

        //Cоздали правила
        $ruleFrequentVisitorRule = new \common\components\rbac\rules\FrequentVisitorRule;
        $auth->add($ruleFrequentVisitorRule);

        //Создали разрешение частого посетителя
        $permfrequentVisitor= $auth->createPermission(Rbac::PERM_FREQUENT_VISITOR);
        $permfrequentVisitor->description = 'Разрешение для частых посетителей';
        //Добавим правила в роль и разрешение
        $permfrequentVisitor->ruleName = $ruleFrequentVisitorRule->name;
        
        //Создадим разрешение в базе данных
        $auth->add($permfrequentVisitor);
        
        $this->stdout('Permission: frequent-visitor is created' . PHP_EOL);
    }

    /**
     * Add permission to role
     * In console run yii rbac/add-permission-to-role guest perm-frequent-visitor
     *
     * @param string $role
     * @param string $permission
     * @return void
     */
    public function actionAddPermissionToRole($role, $permission)
    {
        $auth = Yii::$app->authManager;

        $role = $auth->getRole($role);
        $perm = $auth->getPermission($permission);
        $auth->addChild($role, $perm);

        $this->stdout('Role: ' . $role . ' attached with ' .$perm. PHP_EOL);
    }

Для названий ролей и разрешений создадим класс для хранения констант имен, чтобы в дальнейшем пользоваться ими в момент проверки разрешений:

<?php

namespace common\components\rbac;
 
final class Rbac
{
    
    const PERM_FREQUENT_VISITOR = 'perm-frequent-visitor';
    
    const ROLE_GUEST = 'guest';

}

Теперь перейдем в консоли в корень проекта  и по очереди запустим комманды для создания ролей:

yii rbac/create-default-role-guest

yii rbac/create-frequent-visitor-permission

yii rbac/add-permission-to-role guest perm-frequent-visitor

Если команды отработали без ошибок, то разрешения и их зависимости создались в базе данных. Можем протестировать в работе. Создадим в файле вида условие и запустим страницу в браузере:

if (\Yii::$app->user->can(Rbac::PERM_FREQUENT_VISITOR)){
    echo "Здравствуйте, Гость! Это Ваш 10 визит. Зареестрируйтесь ... и т.п.";           
}

Теперь этот код отработает, если обновить страницу 10 раз. На 11 - сообщение пропадет. Для зарегестрированного пользователя показываться не будет, т.к. разрешение привязано к ролителю 'guest' с правилом для определения гостя.
Даже если 'правило' будет возвращать false и роль не будет активирована, код в классе 'правила' будет отробатывать и, как в примере cookie будут перезаписываться.

Принцип работы правил. Частые заблождения.

Правила позволяют добавить дополнительную обработку к ролям и разрешениям. Результатом работы правила, 'привязанного' к роли и разрешению является true или false и соответственно результаты проверки прав зависят от логики в правилах. Важно понимать, что rbac - это иерархическая система прав и ролей. Поэтому, роль может быть дочерней для другой роли. Право иметь родительское право и роль. 
Право не может быть родительским элементом для роли. 
Когда создается роль и к ней привязывается правило, то дочерняя роль или разрешение со своим правилом также зависит от родительского правила, а не наоборот.
Напимер, если мы создадим роль 'user' и привяжем к нему какое-то правило, а потом создадим роль 'guest' и привяжем к нему свое правило, то при проверки доступа прав для гостя сначала отработает проверка правила родительской роли 'user' , а потом только правило роли 'guest'. 

Т.е. правила проверяются "сверху-вниз", а не формируют набор правил для родительской роли. Так происходит потому, что во время проверки прав в коде рекурсивно проверяются все привязанные правила, начиная от родительского элемента. И если родитель вернул false, то проверка не пройдена, хотя код отработает в полном объеме и у дочернего элемента, но метод уже в любом случае вернет false и проверка будет не пройдена.

Методы для взаимодействия в yii\rbac\DbManager

Рассмотрим методы для взаимодействия с rbac:
//Экземпляр менеджера
$auth = Yii::$app->authManager;

//Создание роли и разрешения
$auth->createRole('name');
$auth->createPermission('name');

//Добавить данные в объекты роли или разрешения
$item->description = 'Some';

//Сохранение объекта роли, разрешения или правила в хранилище
$auth->createPermission($obj);

//Получить роль или разрешение по имени и
//Возвращает объект
$role = $auth->getRole('role');
$perm = $auth->getPermission('permission');

//Получить все роли, что есть в rbac
$auth->getRoles();//массив объектов

//Получить все default роли, что есть в rbac в виде массива
$auth->getDefaultRoles();//вернет массив строк названий
$auth->getDefaultRoleInstances();//вернет массив объеков

//Добавить роль или разрешение в систему
//$item - объект роли или разрешения
$auth->add($item);

//Добавить роли по умолчанию в систему
//$roles - массив или анонимная функция, возвращающая массив
$auth->setDefaultRoles($roles);

//Добавить правило к роли или разрешению
$rule = new \Rule;
$role->ruleName = $rule->name;

//Добавить роль или разрешение в качестве дочернего
//$role - родительское поле, $role - дочернее
$auth->addChild($role, $perm);

//Обновление роли или разрешение
//$name - имя объекта
//$object - объект роли или разрешения
$auth->update($name, $object);

//Удалить объект - роль, разрешение или правило с rbac систеты
$auth->remove($object);

//Проверка наличия дочернего разрешения или роли в DbManager
//$parent, $child - объекты
$auth->hasChild($parent, $child);

//Возвращает все дочерние роли и разрешения в виде массива объектов в DbManager
//$name - роль или разрешение
$auth->getChildren($name);

//Привязывает роль к пользователю по user id
//$role - объект роли или разрешения
$auth->assign($role, $userId);

//Удаляет связь роли и пользователя по user id
//$role - объект роли или разрешения
$auth->revoke($role, $userId);

//Удалить все права и разрешения у пользователя по user id
$auth->revokeAll($userId);

//Удалить все данные из таблиц rbac
$auth->removeAll();

//Удалить все разрешения из бд rbac
$auth->removeAllPermissions();

//Удалить все роли из бд rbac
$auth->removeAllRoles();

//Удалить все правила из бд rbac
$auth->removeAllRules();

//Удалить все связи пользователей и ролей (разрешений) из бд rbac
$auth->removeAllAssignments();

//Очистить кеш данных rbac
$auth->invalidateCache();

//Загрузить из кеша данные rbac
$auth->loadFromCache();

//Загрузить все id пользователей rbac по имени роли или разрешению
//Вернет массив с id
$auth->getUserIdsByRole($roleName);
В данном списке я указал все публичные методы для работы с Yii2 RBAC DbManager.

Краткий анонс следующей части про rbac.

Кэш используется для повышения производительности RBAC.
В следующей части я покажу как кэшировать данные RBAC, как подключать различные хранилища для кэширования и обновлять кэш при изменении данных в rbac.

Однако кэширование требует дополнительной памяти и, как следствие, может не подходить, если ваша система RBAC содержит слишком много элементов аутентификации. В этом случае вам следует искать другие реализации RBAC (например, RBAC на основе хранилища Redis).

Поэтому уделим работе rbac в связки с redis, используя yii2-redis особое внимание...

Читайте также из этой серии:

Приветствую!

Меня зовут Сергей. Я - автор этого блога.

Если Вам был полезен материал на моем сайте, поддержите пожалуйста мой проект, чтобы о нем узнали другие люди - кликните plizz :) на иконку в соц. сети, чтобы поделиться материалом с другими.