Контроль доступа к модулю в Yii2

У меня проблема с частью входа в систему. Я прочитал эту тему: http://www.yiiframework.com/wiki/771/rbac-super-simple-with-admin-and-user/ . Затем я следую его шагам, но на шаге 6 он настраивается только для одного контроллера. У меня есть модуль под названием Admin со многими контроллерами, и я не знаю, как применить этот контроль доступа ко всему модулю. Может кто-нибудь помочь мне ? Извините за мой плохой английский.


person user1571234    schedule 19.06.2015    source источник


Ответы (5)


Вы можете создать класс AdminController, который будет расширять yii\web\Controller, где вы определяете свои правила доступа в методе behaviors и заставляете другие контроллеры модулей расширять ваш AdminController и переопределять метод behaviors следующим образом:

public function behaviors()
{
    return \yii\helpers\ArrayHelper::merge(parent::behaviors(), [
        'verbs' => [
            'class' => VerbFilter::className(),
            'actions' => [
                'delete' => ['post'],
            ],
        ],
    ]);
}

Здесь parent::behaviors() — это поведения из AdminController, которые определяют правила доступа по умолчанию, и вы объединяете их с конкретными поведениями в дочернем контроллере. Это дает вам возможность переопределять некоторые правила доступа, если вам это нужно.

person Tony    schedule 19.06.2015
comment
Итак, модуль Yii2 не имеет метода поведения, верно? - person user1571234; 20.06.2015
comment
@user1571234 user1571234 имеет, и если вы хотите иметь правила доступа для всего модуля, и ни один из его контроллеров не будет иметь разных правил доступа, вы можете определить их в методе behaviors модуля. Определение правил доступа в родительском контроллере и их наследование дает вам больше гибкости, если вам нужно другое поведение для некоторых из ваших контроллеров. - person Tony; 21.06.2015

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

1. Добавьте поле role в модель пользователя и оцените его значением одной из констант из примера статьи (User::ROLE_ADMIN или User::ROLE_USER).

2. Переопределить yii\web\User->can()

public function can($permissionName, $params = [], $allowCaching = true)
{
    /** @var \app\models\User $user */
    $user = $this->identity;
    $access = false;
    do {
        if (\Yii::$app->user->isGuest) {
            break;
        }

        if ($user->role === \common\models\User::ROLE_ADMIN) {
            $access = true;
            break;
        }

        if (is_array($permissionName)) {
            $access = in_array($user->role, $permissionName);
        } else {
            $access = $permissionName === $user->role;
        }
    } while (false);

    return $access;
}

Итак, теперь вы можете проверить роль пользователя следующим образом:

\Yii::$app->user->can(User::ROLE_USER)

3. Вы говорите:

я не знаю, как применить этот контроль доступа ко всему модулю.

Затем откройте класс вашего модуля и добавьте в метод поведения() следующее:

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'allow' => true,
                    'roles' => [User::ROLE_ADMIN]
                ]
            ]
        ]
    ];
}

В этом примере мы предоставляем доступ ROLE_ADMIN ко всем действиям всех контроллеров вашего модуля. Вот и все.

person no_igor    schedule 23.09.2015

Создайте пользовательскую модель AccessRules.php, как показано ниже:

<?php 
namespace app\models;


class AccessRules extends \yii\filters\AccessRule
{

    /**
     * @inheritdoc
     */
    protected function matchRole($user)
    {
        if (empty($this->roles)) {
            return true;
        }
        foreach ($this->roles as $role) {
            if ($role === '?') {

                if ($user->getIsGuest()) {
                    return true;
                }
            } elseif ($role === '@') {
                if (!$user->getIsGuest()) {
                    return true;
                }
            // Check if the user is logged in, and the roles match
            } elseif (!$user->getIsGuest() && (int)$role === $user->identity->user_role) {
               return true;
            }
        }

        return false;
    }
}
?>

Теперь откройте контроллер вашего сайта и добавьте следующий код в часть функционального поведения:

use app\models\AccessRules;
 public function behaviors()
   {
        return [
            'access' => [
                    'class' => AccessControl::className(),
    // We will override the default rule config with the new AccessRule class
    'ruleConfig' => [
        'class' => AccessRules::className(),
    ],
    'only' => ['create', 'update', 'delete','index'],
    'rules' => [
        [
            'actions' => ['create', 'update', 'delete','index'],
            'allow' => true,
            // Allow admin to create
            'roles' => [
                '1' 
            ],
        ]
    ],
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'logout' => ['post'],
                ],
            ],
        ];
    }
person Ankush Rishi    schedule 20.06.2015
comment
для ясности вы использовали user_role. Столбец role создается со значением по умолчанию 10 при использовании расширенных и запущенных миграций Yii2. Не то чтобы вы не можете изменить это :) На всякий случай, если кто-то еще наткнется здесь, я хотел отметить эту разницу. - person Wade; 02.10.2015

Согласно Руководству по Yii2, "ACF — это фильтр действий, который может использоваться в контроллере или модуле» таким же образом.

person mariovials    schedule 09.06.2017

Просто добавьте ниже код в контроллер, который вы хотите ограничить функциональность

        'access' => [
            'class' => AccessControl::className(),

            'rules' => 
            [
                [
                    'actions' => ['index','view'],
                    'allow' => true,
                    'roles' => ['@']
                ],

                [
                    'actions' => ['create','update','delete'],                            
                    'allow' => true,
                    'roles' => ['@'],

                     'matchCallback' => function ($rule, $action) 
                     {
                            return Admin::isUserAdmin(Yii::$app->user->identity->username);
                    }
                ],
             ],

        ],
person Farhan Shafique    schedule 02.01.2018