RBAC в Yii2

суббота, 6 декабря 2014 09:04:43, написал Admin

Наконец-то я вернулся к любимому Yii. И сразу пришлось обкатывать вторую версию. О новшествах и отличиях расскажу в другой раз. Цель этой статьи – познакомится с организацией доступа по ролям пользователей в Yii2 (RBAC).

Роли пользователей будем хранить в базе данных. Для реализации задачи возьмем стандартный модуль rbac, поставляемый по молчанию в Yii2.

Установка

Сначала настроим конфиг. В компонентах пропишем

    'components' => [
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
            'defaultRoles' => [
                'user',
                'moderator',
                'admin',
                'superadmin'
            ],
        ],
        'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
        ],
…
]

У нас есть четыре роли. В модели User добавляем строковое поле role.

Создаем таблицы правил ролей. Можно через миграции, но я сразу выполнил импорт в базу данных файла

\vendor\yiisoft\yii2\rbac\migrations\schema-mysql.sql

Пишем класс правила для ролей:

namespace app\components\rbac;

use Yii;
use yii\rbac\Rule;

/**
 * User group rule class.
 */
class GroupRule extends Rule
{
    /**
     * @inheritdoc
     */
    public $name = 'group';

    /**
     * @inheritdoc
     */
    public function execute($user, $item, $params)
    {
        if (!Yii::$app->user->isGuest) {
            $role = Yii::$app->user->identity->role;

            if ($item->name === 'superadmin') {
                return $role === $item->name;
            } elseif ($item->name === 'admin') {
                return $role === $item->name || $role === 'superadmin';
            } elseif ($item->name === 'moderator ') {
                return $role === $item->name || $role === 'superadmin' || $role === 'admin';
            } elseif ($item->name === 'user') {
                return $role === $item->name || $role === 'superadmin' || $role === 'admin' || $role === 'moderator';
            }
        }
        return false;
    }
} 

Пишем класс консольной команды для занесения ролей в базу данных

namespace app\commands;

use Yii;
use yii\console\Controller;
use app\components\rbac\GroupRule;
use yii\rbac\DbManager;

/**
 * RBAC console controller.
 */
class RbacController extends Controller
{
    /**
     * Initial RBAC action
     * @param integer $id Superadmin ID
     */
    public function actionInit($id = null)
    {
        $auth = new DbManager;
        $auth->init();

        $auth->removeAll(); //удаляем старые данные
        // Rules
        $groupRule = new GroupRule();

        $auth->add($groupRule);

        // Roles
        $user = $auth->createRole('user');
        $user->description = 'User';
        $user->ruleName = $groupRule->name;
        $auth->add($user);

        $moderator = $auth->createRole(' moderator ');
        $moderator ->description = 'Moderator ';
        $moderator ->ruleName = $groupRule->name;
        $auth->add($moderator);
        $auth->addChild($moderator, $user);

        $admin = $auth->createRole('admin');
        $admin->description = 'Admin';
        $admin->ruleName = $groupRule->name;
        $auth->add($admin);
        $auth->addChild($admin, $moderator);

        $superadmin = $auth->createRole('superadmin');
        $superadmin->description = 'Superadmin';
        $superadmin->ruleName = $groupRule->name;
        $auth->add($superadmin);
        $auth->addChild($superadmin, $admin);

        // Superadmin assignments
        if ($id !== null) {
            $auth->assign($superadmin, $id);
        }
    }
}

Выполняем команду

php yii rbac/init

Если хотим просто добавить роли или

php yii rbac/init 1

- если хотим привязать роль супердамина пользователю с id=1 И наконец в модели пользователей, после добавления или обновления присваиваем роль:

   public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);
        // установка роли пользователя
        $auth = Yii::$app->authManager;
        $name = $this->role ? $this->role : self::ROLE_USER;
        $role = $auth->getRole($name);
        if (!$insert) {
            $auth->revokeAll($this->id);
        }
        $auth->assign($role, $this->id);
    }

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

В контролере пишем

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

Мы разрешили просматривать всем зарегистрированным пользователям 'index' и 'view', остальные экшены доступны только админам.
В любом месте приложения можно вызывать

If (Yii::$app->user->can('admin')) { … }

Для проверки роли пользователя.
На этом все.

Yii Yii2 Yii
  

Поделиться статьей с друзьями:

  

Комментарии к статье