@lilwings

Как можно заполнить AccessControl в yii2?

В общем нужно сделать так:

1) Не авторизованный пользователь мог только авторизоваться и все.
2) Авторизованный мог все

И если не трудно с объяснениями, не могу что то разобраться, вроде легко в в роде и нет)) Буду благодарен.

P.S: Вот так сделал, но если в разных контроллераз у action будут одинаковые имена?

namespace backend\controllers;

use yii\web\Controller;
use yii\filters\AccessControl;

class AppController extends Controller
{
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['login', 'logout', 'signup'],
                'rules' => [
                    [
                        'allow' => true,
                        'actions' => ['auth'],
                        'roles' => ['?'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['*'],
                        'roles' => ['@'],
                    ],
                ],
            ],
        ];
    }
}
  • Вопрос задан
  • 121 просмотр
Решения вопроса 1
myks92
@myks92 Куратор тега Yii
Нашёл решение — пометь вопрос ответом!
Вы все сделали правильно, однако, когда пользователь гость — фильтры yii2 автоматически редиректят его на страницу входа.

По умолчанию адрес входа: site/login. Адрес можно поменять в компоненте user приложения. По умолчанию используется класс yii\web\User Чтобы поменять путь к логину необходимо настроить user компонент в config.

Так как у вас advanced шаблон и имеются два приложения (backend и frontend), то возможны два способа настроек:

1. Если форма входа общая
//common/config/main.php
'user' => [
    'loginUrl' => ['/admin/auth/login']
],

2. Если форма входа разные:
//backend/config/main.php
'user' => [
    'loginUrl' => ['/admin/auth/login']
],

//frontend/layout/main.php
'user' => [
    'loginUrl' => ['/auth/login']
],

Так же можно вызвать форму из шаблона по js
//config
'user' => [
    'loginUrl' => ['/?login=true']
],

//frontend/layout/main.php
$script = <<< JS
$('#login').trigger('click'); //вызываем окно с формой логина
JS;

Существует минимум три способа для перекрытия страниц общими правилами фильтрации:

1. Помещаем общие правила в «главный» контроллер, от которого наследуются все контроллеры приложения.
2. Прикрепляем глобальный фильтр с общими правилами, который будет перекрывать все экшены приложения.
3. Выносим общие правила в отдельные классы-фильтры, которые можно подключить в контроллере, модуле или во всем приложении.

Рекомендую использовать третий вариант. Не рекомендую использовать первый вариант. В некоторых случаях — второй.

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

Если мы разрабатываем приложение, в котором есть не только web controller, но так же api controller, console controller, то при таком подходе нам необходимо создать три контроллера с одинаковыми общими правилами или применить ещё один уровень наследования. В конечном итоге от дублирования кода или от большой вложенности кода не уйти.

Если мы оставим три общих контроллера, то при изменении правил, мы можем забыть изменить их в другом месте. Из-за чего что-то будет работать не запланировано.

Второй вариант дает нашему коду некую «загадочность» (магию), а так же усложняет тестирование.

При использовании 3 варианта код редактируется всегда в одном файле на все контроллеры модули и приложения. Код тестируется отдельно от контроллеров и соответствует SOLID.

На эту тему можно посмотреть Дмитрия Елисеева.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы