Yii2 создание блога (Часть 7 – Управление правами доступа)

В Yii Framawork 2 поддерживается две модели управления правами доступа: ACL (Access Control Filter ) и RBAC (Role-Based Access Control). В данной заметке хочу рассмотреть модель ACL, так как она более проста в реализации и в полной мере удовлетворяет потребности для разделения прав. Часть ниже описанного будет подходить так же к RBAC, в частности схема генерации ролей.

Подключим “Auth manager”:

return [
    'components' => [
        // ...
        'authManager' => [
            'class' => 'yii\rbac\PhpManager',
            'defaultRoles' => ['user', 'admin'],
            'itemFile' => '@common/config/rbac/items.php',
            'assignmentFile' => '@common/config/rbac/assignments.php',
            'ruleFile' => '@common/config/rbac/rules.php'
        ],
    ],
];

После этого создаём директорию rbac по пути @common/config/rbac, для того, что бы эта директория добавилась в репозиторий, в ней можно создать пустой файл .gitkeep

Внесём корректировку в модель пользователей, добавим константу, хранящую идентификатор роли администратора:

class User extends ActiveRecord implements IdentityInterface
{
    // ...
    const ROLE_ADMIN = 100;
    // ...
}

Добавим класс (console/models/UserRoleRule), описывающий роль пользователя:

namespace console\models;

use common\models\User;
use yii\helpers\ArrayHelper;
use yii\rbac\Rule;

/**
 * Класс описывающий роль пользователя.
 */
class UserRoleRule extends Rule
{
    public $name = 'userRole';

    /**
     * {@inheritdoc}
     */
    public function execute($user, $item, $params)
    {
        $user = ArrayHelper::getValue($params, 'user', User::findOne($user));

        if ($user) {
            $role = (int) $user->role;

            if ($item->name === 'admin') {
                return $role === User::ROLE_ADMIN;
            } elseif ($item->name === 'user') {
                return $role === User::ROLE_ADMIN || $role === User::ROLE_USER;
            }
        }

        return false;
    }
}

Метод execute выполняет проверку правила.

Для генерации иерархии ролей создадим в консольном приложении контроллер (console/controllers/RbacController), содержащий иерархию ролей:

<?php
namespace console\controllers;

use console\models\UserRoleRule;
use yii\console\Controller;

/**
 * Контроллер формирующий права доступа на сайте.
 */
class RbacController extends Controller
{
    public function actionInit()
    {
        $auth = \Yii::$app->authManager;
        $auth->removeAll();

        $rule = new UserRoleRule();
        $auth->add($rule);

        $user = $auth->createRole('user');
        $user->description = 'Пользователь';
        $user->ruleName = $rule->name;
        $auth->add($user);

        $admin = $auth->createRole('admin');
        $admin->description = 'Администратор';
        $admin->ruleName = $rule->name;
        $auth->add($admin);

        $auth->addChild($admin, $user);
    }
}

После того, как созданы модель и контроллер, в консольном приложении должна появиться команда rbac/init, необходимо её выполнить, после чего будет сгенерированно 3 файла в директории: @common/config/rbac

Управление правами доступа происходит путём добавления секции access в массив, возвращаемый методом behaviors принадлежащим к контроллерам. Рассмотрим на примере админского контроллера категорий:

public function behaviors()
{
    return [
        // ...
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => ['index', 'view', 'create', 'update', 'delete'],
                    'allow' => true,
                    'roles' => ['admin'],
                ],
            ],
        ],
        // ...
    ];
}

Здесь перечисляются имена action и список ролей, которые могут их выполнять.

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