Yii2 для Блондинок и чайников

Введение

Очень часто при разработки веб приложений, нам необходимо иметь возможность гибких настроек, над привилегиями пользователей системы.
С этой задачей в YII2 хорошо справляется менеджер RBAC.
Менеджер RBAC бывает 2-типов:

  • yii\rbac\PhpManager - Основанный на хранения в файлах.
  • yii\rbac\DbManager - Основанный на хранения в БД.

В этой статье мы разберем работу yii\rbac\DbManager, так как по моему мнению он более гибче и практичней чемyii\rbac\PhpManager.

Настройка RBAC

Первым делом нам необходимо подключить данный менеджер в конфиг, не забывайте подключить и в конфигу консольного приложения:

$config = [
    //..
    'components' => [
        //..
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
            'cache' => 'cache' //Включаем кеширование 
        ],
        'cache' => [
            'class' => 'yii\caching\FileCache',  // Подключаем файловое кэширование данных
        ],
    ]
    //..
];

Если вы для своих проектов используете кеширование, то для DbManager можно указать дополнительное свойство cache, что позволит существенно снизить нагрузку с бд.

После этого нам необходимо в консоли выполнить команду:

php yii migrate --migrationPath=@yii/rbac/migrations/

Вследствие чего у нас в бд создается 4 таблицы.

Назначения таблиц RBAC

  • таблица auth_item: содержит role/permitssion и их описание.
  • таблица auth_item_child: содержит наследования role/permitssion друг от друга.
  • таблица auth_assignment: хранит данные о назначении пользователям role/permitssion.
  • Таблица auth_rule: для хранения индивидуальных правил.

Настройка Role и Permission

Теперь когда мы выполнили миграцию таблиц, нужно добавить несколько ролей (role).

$role = Yii::$app->authManager->createRole('admin');
$role->description = 'Администратор';
Yii::$app->authManager->add($role);
 
$role = Yii::$app->authManager->createRole('author');
$role->description = 'Автор';
Yii::$app->authManager->add($role);

Теперь когда у нас появились новые роли в системе, мы можем их использовать в фильтр AccessControl, для настройки доступа.

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => ['adminka'],
                    'allow' => true,
                    'roles' => ['admin'],
                ],
            ],
        ]
}

Доступ к actionAdminka доступен только пользователю с ролью admin. Но пользователя с такой ролью у нас пока нет. Пока есть только роль. Что еще важно: создавать можно не только роль, но и отдельные право (Permission).
Создаются они так же как и роли:

$permit = Yii::$app->authManager->createPermission('createPost');
$permit->description = 'Право на создании поста';
Yii::$app->authManager->add($permit);

Yii не проверяет сам права. Имя «createPost» — просто строка, она никак не соотносится с action и другими сущностями Yii. Проверять, имеет ли право юзер на действия вы должны сами.

if(\Yii::$app->user->can('createPost'))
{
    //выполняем какое то действие
}
else throw new ForbiddenHttpException('У вас недостаточно прав для выполнения указанного действия');

Наследования ролей и прав

Роли и права можно наследовать. Причем без ограничений что от чего наследуется.

$role = Yii::$app->authManager->getRole($name);
$permit = Yii::$app->authManager->getPermission($permit);
Yii::$app->authManager->addChild($role, $permit);

Наследовать можно:

  • роль от роли
  • роль от права
  • право от роли
  • право от права

Пример: роль админа наследует все права от роли автора (что разрешено пользователю становится доступно админу).
Уровень вложенности наследуемых прав не ограничен.

Привязка ролей к пользователю

Назначение роли так же делается через authManager.

$userRole = Yii::$app->authManager->getRole('name_of_role');
Yii::$app->authManager->assign($userRole, Yii::$app->user->getId());

И делается 1 раз. RBAC сохранит данные в auth_assignment и будет подхватывать роль автоматически при авторизации пользователя. Поэтому привязку лучше всего делать при заведении пользователя.
Важно то, что привязывать к пользователю можно не только роль, но и право.

$permit = Yii::$app->authManager->getPermission('name_of_permitssion');
Yii::$app->authManager->assign($permit, Yii::$app->user->getId());

У пользователя может быть несколько ролей. Получить их всех можно вот так:

Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId())

Использование (Rules)

Теперь когда мы научились использовать роли и право , мы можем приступить к рассмотрению использования правил (Rules).Правила добавляет дополнительное ограничение на роли и право. Для создания своего правила, нам необходимо унаследоваться от класса yii\rbac\Rule и реализовать метод execute().

namespace app\rbac;
 
use yii\rbac\Rule;
 
class AuthorRule extends Rule
{
    public $name = 'isAuthor'; // Имя правила
 
    public function execute($user_id, $item, $params)
    {
        return isset($params['post']) ? $params['post']->createdBy == $user_id : false;
    }
}

Это правило будет следить за тем что, является ли данный пост текущего пользователя.

$auth = Yii::$app->authManager;
 
// добовляем правило
$rule = new \app\rbac\AuthorRule;
$auth->add($rule);
 
// добавляем право "updateOwnPost" и связываем правило с ним
$updateOwnPost = $auth->createPermission('updateOwnPost');
$updateOwnPost->description = 'Редактировать посты';
$updateOwnPost->ruleName = $rule->name;
$auth->add($updateOwnPost);
 
// "updateOwnPost" наследует право "updatePost"
$updatePost = Yii::$app->authManager->getPermission('updatePost');
$auth->addChild($updateOwnPost, $updatePost);
 
$author = Yii::$app->authManager->getRole('author');
// и тут мы позволяем автору редактировать свои посты
$auth->addChild($author, $updateOwnPost);

Теперь мы для проверке в коде пишем следующий код

if (\Yii::$app->user->can('updatePost', ['post' => $post])) {
    // update post
}

Как мы видим правило updatePost принимает модель post, где updatePost передаёт на обработку праву updateOwnPost а он в свою очередь вызывает правило AuthorRule и запускает метод execute() который возвращает true/false. В случаи успеха данный пост будет отредактирован.

Оригинал статьи: http://wiki.it-wiki.org.ua/doku.php/yii2:rbac

сумма должна быть от 50 до 100000
help
Имя, которое будет отображаться на странице спонсоров. Можно вписать любое имя, бренд или оставить пустым.
help
Можно оставить пустым, можно написать любой текст, можно указать ссылку или бренд, нельзя использовать сленг и html. Этот текст появится на странице спонсоров. Сортировка спонсоров по сумме, думаю это честно.