RBAC. Не работает редирект в AccessControl

Уже исправленные репорты или принятые предложения
whisperer
Сообщения: 9
Зарегистрирован: 2014.06.07, 19:25

RBAC. Не работает редирект в AccessControl

Сообщение whisperer »

Допустим, есть такой behavior в контроллере

Код: Выделить всё

public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'actions' => ['login', 'error'],
                        'allow' => true,
                    ],
                    [
                        'actions' => ['logout', 'index'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                    [
                        'actions' => ['test'],
                        'allow' => true,
                        'roles' => ['3'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'logout' => ['post'],
                ],
            ],
        ];
    } 
Если обратиться к экшну "тест" как зарегистрированный пользователь, например под ролью 1, то Yii выдаст страницу 403. как и должно быть.
Теперь так. Если выйти из аккаунта и снова обратится к этому же экшну, то получим белый пустой экран.
Или же так: если поставить вместо тройки в 'roles' какую нибудь несуществующую роль, и попробовать обратиться к экшну, то тоже получим белую пустую страницу.

А причиной, как мне кажется, является метод $this->denyAccess($user), вызываемый в beforeAction в классе AccessControl (строка 133), который в свою очередь вызывает loginRequired(), если пользователь гость, и затем loginRequired пытается выполнить редирект return Yii::$app->getResponse()->redirect($this->loginUrl), который не срабатывает.

И вообще. Этот экшн выполняется и происходит редирект.

Код: Выделить всё

public function actionTest1()
    {
        return Yii::$app->getResponse()->redirect(Yii::$app->user->loginUrl);
    }
а этот уже не рабочий. пустая белая страница

Код: Выделить всё

public function actionTest1()
    {
        $m = Yii::$app->authManager->getRules(); // или другие методы authManager'a или просто authManager
        return Yii::$app->getResponse()->redirect(Yii::$app->user->loginUrl);
    }
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: RBAC. Не работает редирект в AccessControl

Сообщение zelenin »

белый экран означает что у вас отключен debug и произошла ошибка.
whisperer
Сообщения: 9
Зарегистрирован: 2014.06.07, 19:25

Re: RBAC. Не работает редирект в AccessControl

Сообщение whisperer »

debug включен.
и вот то выдает по запросу к этому экшну.
1 11:37:22.238 trace yii\base\Application::bootstrap Bootstrap with yii\log\Dispatcher
2 11:37:22.238 trace yii\base\Module::getModule Loading module: debug
3 11:37:22.253 trace yii\base\Application::bootstrap Bootstrap with yii\debug\Module::bootstrap()
4 11:37:22.256 trace yii\base\Module::getModule Loading module: gii
5 11:37:22.257 trace yii\base\Application::bootstrap Bootstrap with yii\gii\Module::bootstrap()
6 11:37:22.261 trace yii\web\UrlManager::parseRequest Pretty URL not enabled. Using default URL parsing logic.
7 11:37:22.261 trace yii\web\Application::handleRequest Route requested: 'site/test1'
8 11:37:22.267 trace yii\base\Controller::runAction Route to run: site/test1
9 11:37:22.276 trace yii\base\InlineAction::runWithParams Running action: backend\controllers\SiteController::actionTest1()

А вот что выдает, если обратиться к экшну test, на который поставлены ограничения по ролям
1 11:42:09.657 trace yii\base\Application::bootstrap Bootstrap with yii\log\Dispatcher
2 11:42:09.658 trace yii\base\Module::getModule Loading module: debug
3 11:42:09.672 trace yii\base\Application::bootstrap Bootstrap with yii\debug\Module::bootstrap()
4 11:42:09.675 trace yii\base\Module::getModule Loading module: gii
5 11:42:09.676 trace yii\base\Application::bootstrap Bootstrap with yii\gii\Module::bootstrap()
6 11:42:09.680 trace yii\web\UrlManager::parseRequest Pretty URL not enabled. Using default URL parsing logic.
7 11:42:09.680 trace yii\web\Application::handleRequest Route requested: 'site/test'
8 11:42:09.686 trace yii\base\Controller::runAction Route to run: site/test
9 11:42:09.703 info yii\web\Session::open Session started
astronin
Сообщения: 606
Зарегистрирован: 2012.01.30, 17:46

Re: RBAC. Не работает редирект в AccessControl

Сообщение astronin »

проверьте action test вообще без настройки доступов, кажется его не может найти
whisperer
Сообщения: 9
Зарегистрирован: 2014.06.07, 19:25

Re: RBAC. Не работает редирект в AccessControl

Сообщение whisperer »

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

Код: Выделить всё

    public function beforeAction($action)
    {
        $user = $this->user;
        $request = Yii::$app->getRequest();
        /** @var AccessRule $rule */
        foreach ($this->rules as $rule) {
            if ($allow = $rule->allows($action, $user, $request)) {
                return true;
            } elseif ($allow === false) {
                if (isset($rule->denyCallback)) {
                    call_user_func($rule->denyCallback, $rule, $action);
                } elseif (isset($this->denyCallback)) {
                    call_user_func($this->denyCallback, $rule, $action);
                } else {
                    $this->denyAccess($user);
                }
                return false;
            }
        }
        if (isset($this->denyCallback)) {
            call_user_func($this->denyCallback, null, $action);
        } else {
            Yii::error("1) Class: ".__CLASS__."; Function: ".__FUNCTION__."; Line: ".__LINE__);
            $this->denyAccess($user); // <<<========= ПОПАДАЕМ СЮДА =============
        }
        return false;
    } 
Затем вызывается это метод

Код: Выделить всё

protected function denyAccess($user)
    {
        if ($user->getIsGuest()) {
            Yii::error("2) Class: ".__CLASS__."; Function: ".__FUNCTION__."; Line: ".__LINE__);
            $user->loginRequired(); //  <<<======================
        } else {
            throw new ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.'));
        }
    }
А вот где, собственно и происходит непонятная ситуация

Код: Выделить всё

    public function loginRequired()
    {
        $request = Yii::$app->getRequest();
        if (!$request->getIsAjax()) {
            $this->setReturnUrl($request->getUrl());
        }
        if ($this->loginUrl !== null) {
            Yii::error("НЕ ПРОИСХОДИТ РЕДИРЕКТ. Class: ".__CLASS__."; Function: ".__FUNCTION__."; Line: ".__LINE__);
            return Yii::$app->getResponse()->redirect($this->loginUrl); //  <<<=========  Тут не происходит редирект
        } else {
            throw new ForbiddenHttpException(Yii::t('yii', 'Login Required')); 
        }
    } 
Скрин дебагера
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: RBAC. Не работает редирект в AccessControl

Сообщение zelenin »

ну если так глубоко залезли, продебажьте дальше - что в loginUrl, что происходит в redirect?
whisperer
Сообщения: 9
Зарегистрирован: 2014.06.07, 19:25

Re: RBAC. Не работает редирект в AccessControl

Сообщение whisperer »

вобщем докопал я до метода $this->getHeaders()->set('Location', $url) в web\response.php. пытался заменить этот метод на обычный header() c любым другим урлом, так он тоже не работал. перед этим проверка на headers_send показывала что до этого никакой отправки не было. забил я на всё это дело переустановил yii. как ни странно, с теми же настройками теперь всё работает. интересно однако...

и кстати, почему yii вместо site/index генерирует site%2Findex. зачем слеш то экранировать. для чего urlencode() в методе CreateUrl ?
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: RBAC. Не работает редирект в AccessControl

Сообщение samdark »

Энкодить по спецификации необходимо. Нам потребовалось для oauth. Кажется, Google не хотел работать без энкода.
Аватара пользователя
Dementorpasha
Сообщения: 39
Зарегистрирован: 2013.06.08, 07:33

Re: RBAC. Не работает редирект в AccessControl

Сообщение Dementorpasha »

site%2Findex - а можно переключить без кастылей на "/" ?
Avgusto
Сообщения: 46
Зарегистрирован: 2013.11.07, 21:09

Re: RBAC. Не работает редирект в AccessControl

Сообщение Avgusto »

Sam Dark писал(а):Энкодить по спецификации необходимо. Нам потребовалось для oauth. Кажется, Google не хотел работать без энкода.
Dementorpasha писал(а):site%2Findex - а можно переключить без кастылей на "/" ?
да, мне вот тоже очень интересно, а как быть с URL?
Я сначала грешил на виндовый опен-сервер. А оно "вон_чо"...
Даже нагуглил целый мануал в котором это "неудобство" упоминается http://www.elisdn.ru/blog/33/generaciia ... orii-v-yii и аж целых три варианта решения! Нагугленный мануал, видимо, по v1.x.
Но урлы кодируются и в голом yii2 basic/advanced и это, мягко говоря, удивительно :shock:
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: RBAC. Не работает редирект в AccessControl

Сообщение zelenin »

Avgusto писал(а): Но урлы кодируются и в голом yii2 basic/advanced и это, мягко говоря, удивительно :shock:
непонятна эта фраза.
Avgusto
Сообщения: 46
Зарегистрирован: 2013.11.07, 21:09

Re: RBAC. Не работает редирект в AccessControl

Сообщение Avgusto »

zelenin писал(а):
Avgusto писал(а): Но урлы кодируются и в голом yii2 basic/advanced и это, мягко говоря, удивительно :shock:
непонятна эта фраза.
Windows + open-server.
Первое знакомство: с виндовой средой, с Yii и с MVC - многовато неизвестных для начала :o
Установил через композер advanced и basic. Всё без ошибок. Октрываю установленные демо. В урлах все слеши закодированы в %2F Например:
/basic/web/index.php?r=site%2Fcontact
/basic/web/index.php?r=site%2Fabout
/advanced/backend/web/index.php?r=site%2Flogin
Грешил на саму рабочую среду - думал может из-за windos или open-server такая особенность.
Да и вроде как даже корректно всё работает. И до поры не зморачивался.
А оно, оказывается, по другой причине так себя ведёт.
Или я неправ?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: RBAC. Не работает редирект в AccessControl

Сообщение zelenin »

Avgusto писал(а):
zelenin писал(а):
Avgusto писал(а): Но урлы кодируются и в голом yii2 basic/advanced и это, мягко говоря, удивительно :shock:
непонятна эта фраза.
Windows + open-server.
Первое знакомство: с виндовой средой, с Yii и с MVC - многовато неизвестных для начала :o
Установил через композер advanced и basic. Всё без ошибок. Октрываю установленные демо. В урлах все слеши закодированы в %2F Например:
/basic/web/index.php?r=site%2Fcontact
/basic/web/index.php?r=site%2Fabout
/advanced/backend/web/index.php?r=site%2Flogin
Грешил на саму рабочую среду - думал может из-за windos или open-server такая особенность.
Да и вроде как даже корректно всё работает. И до поры не зморачивался.
А оно, оказывается, по другой причине так себя ведёт.
Или я неправ?
это так должно быть.
Avgusto
Сообщения: 46
Зарегистрирован: 2013.11.07, 21:09

Re: RBAC. Не работает редирект в AccessControl

Сообщение Avgusto »

zelenin писал(а):это так должно быть.
Avgusto писал(а):...и это, мягко говоря, удивительно :shock:
А подскажите пожалуйста, как сделать нормальные URL адреса?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: RBAC. Не работает редирект в AccessControl

Сообщение zelenin »

Avgusto писал(а):
zelenin писал(а):это так должно быть.
Avgusto писал(а):...и это, мягко говоря, удивительно :shock:
А подскажите пожалуйста, как сделать нормальные URL адреса?
например?
Avgusto
Сообщения: 46
Зарегистрирован: 2013.11.07, 21:09

Re: RBAC. Не работает редирект в AccessControl

Сообщение Avgusto »

zelenin писал(а):например?

Код: Выделить всё

$norm_url = urldecode($url_from_yii); 
best practices, да? Сначала всё закодируем, а потом всё раскодируем. Или снова "мимо пихты"?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: RBAC. Не работает редирект в AccessControl

Сообщение zelenin »

Avgusto писал(а):
zelenin писал(а):например?

Код: Выделить всё

$norm_url = urldecode($url_from_yii);
best practices, да? Сначала всё закодируем, а потом всё раскодируем. Или снова "мимо пихты"?
вы сам с собою?
Avgusto
Сообщения: 46
Зарегистрирован: 2013.11.07, 21:09

Re: RBAC. Не работает редирект в AccessControl

Сообщение Avgusto »

zelenin писал(а):вы сам с собою?
очевидно, да.
Спасибо.
Аватара пользователя
ElisDN
Сообщения: 5841
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: RBAC. Не работает редирект в AccessControl

Сообщение ElisDN »

whisperer писал(а):и кстати, почему yii вместо site/index генерирует site%2Findex. зачем слеш то экранировать. для чего urlencode() в методе CreateUrl ?
В GET-параметрах везде спецсимволы кодируются, вот и получается адрес:

Код: Выделить всё

/index.php?r=site%2Fcontact
А так как у Вас сервер настроен не на папку web, то у Вас выводится:

Код: Выделить всё

/basic/web/index.php?r=site%2Fabout
Перестройте сервер на нужную папку (чтобы работал .htaccess) и поставьте в конфигурации:

Код: Выделить всё

'urlManager' => [
    ...
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    ...
], 
Теперь адрес будет обычным:

Код: Выделить всё

/site/contact
Avgusto
Сообщения: 46
Зарегистрирован: 2013.11.07, 21:09

Re: RBAC. Не работает редирект в AccessControl

Сообщение Avgusto »

@ElisDN, благодарю.
Ответить