Переадресация на другой контроллер / действие из module.php

Я пишу модуль для ACL в ZF2И я почти закончил с этим.

Когда я застрял, когда пользователь не авторизован для доступа к запрашиваемой странице, я хочу перенаправить пользователя на страницу, показывающую 403 сообщение.

Я пытался перенаправить пользователя на 403 но это обновляет URL, так что теперь я пытаюсь переслать пользователя.

Все, что я хочу сделать, это от Module.php, Я пробовал ниже код -

module.php

if (!$isAllowed) {
    $e->getApplication()->getServiceManager()->get('ControllerPluginManager')->get('forward')->dispatch('acl');
}

Используя это я получил следующую ошибку -

Uncaught исключение "Zend\Mvc\Exception\DomainException" с сообщением "Для плагина Forward требуется контроллер, реализующий InjectApplicationEventInterface"

Я также пытался реализовать Acl контроллер с InjectApplicationEventInterface, Но вопрос остается тем же.

Можете ли вы объяснить, как Forward другому Action от Module.php?
Дайте мне знать, если вам нужно больше деталей.

4 ответа

Решение

Что вы можете сделать, так это прослушать событие отправки. Вы можете обновить соответствие маршрута во время этого события, чтобы оно соответствовало паре контроллер / действие, определенной вами для рендеринга страницы 403.

В коде:

use MvcEvent;

class Module
{
    public function onBootstrap($e)
    {
        $app = $e->getApplication();
        $acl = $app->getServiceManager()->get('ACL'); // get your ACL here

        if (!$acl->isAllowed()) {
            $em = $app->getEventManager();
            $em->attach(MvcEvent::EVENT_DISPATCH, function($e) {
                $routeMatch = $e->getRouteMatch();

                $routeMatch->setParam('controller', 'my-403-controller');
                $routeMatch->setParam('action', 'my-403-action');
            }, 1000);
        }
    }
}

Пересылка - это шаблон для отправки контроллера, когда другой контроллер уже отправлен. Это не ваш случай, как я прочитал из вашего вопроса. Так что не используйте плагин forward, но измените соответствие маршрута перед его отправкой.

Вы не можете забыть, но перенаправить на свою страницу 403 следующим образом:

if (!$acl->isAllowed()) {
    $response = $e->getResponse();
    $response->getHeaders()->addHeaderLine('Location', $e->getRequest()->getBaseUrl() . '/403page');
    $response->setStatusCode(403);
}

Я думаю, что если вы хотите отправить пользователю информацию о том, что он находится в зоне ограниченного доступа без обновления URL, вам необходимо:

  1. Измените макет, который показывает ограниченную область сообщения.
  2. Оставьте оригинальный макет и просто переключите шаблоны для вашего действия, чтобы оно показывало сообщение с ограниченным доступом.

После одного из этих действий вы просто меняете Response на 403. Если это то, что вы хотите, это просто сделать. Для любого действия в вашем контроллере вы хотите отправить статус 403 просто используйте:

 $viewModel->setTemplate('partial/noRights');
 $this->getResponse()->setStatusCode('403');
 return $viewModel;

или если вы хотите изменить макет на свой:

 $this->layout('layout/custom');
 $this->getResponse()->setStatusCode('403');
 return $viewModel;

Конечно, вы можете сделать это в разделе начальной загрузки вашего модуля, добавив прослушиватель на event_dispatch и там проверить, если $acl->isAllowed() после этого внесет изменения, которые я написал выше. Пример:

public function onBootstrap(MvcEvent $e)
{
    $app = $e->getApplication();
    $acl = $app->getServiceManager()->get('ACL'); // get your ACL here

    if (!$acl->isAllowed()) {
        $eventManager = $app->getEventManager();
        $sharedEventManager = $eventManager->getSharedManager();
        $sharedEventManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, function($e) {
            $controller = $e->getTarget(); //controller`s action which triggered event_dispatch
            $controller->getResponse()->setStatusCode('403');
            $controller->layout('layout/custom');
        }, 1000);
    }
}

Когда я реализовал ACL, я создал свой собственный модуль AUTH для авторизации и аутентификации.
В этом модуле я создал плагин ACL.. что-то вроде ниже

//Module.php

 /**
     * This method is called once the MVC bootstrapping is complete
     * 
     * @param \Zend\EventManager\EventInterface $e
     */
    public function onBootstrap(Event $e) 
    {
        $services = $e->getApplication()->getServiceManager();

        $eventManager = $e->getApplication()->getEventManager();
        $eventManager->attach('dispatch', array($this, 'loadConfiguration'), 101);
    }

    /**
     * 
     * @param \Zend\Mvc\MvcEvent $e
     */
    public function loadConfiguration(MvcEvent $e) 
    {        
        $e->getApplication()->getServiceManager()
                ->get('ControllerPluginManager')->get('AclPlugin')
                ->checkAcl($e); //Auth/src/Auth/Controller/AclPlugin      
    }

// Auth / SRC /Auth/Controller/AclPlugin

namespace Auth\Controller\Plugin;

/**
 * load libraries here
 */
class AclPlugin extends AbstractPlugin implements ServiceManagerAwareInterface 
{
    /*
     * @var Doctrine\ORM\EntityManager
     */

    protected $em;
    protected $sm;

    /**
     * @param Doctrine\ORM\EntityManager $em
     * @return string
     */
public function checkAcl($e) 
    {

        $matches = $e->getRouteMatch();
        $controller = $matches->getParam('controller');
        $action = $matches->getParam('action', 'index');

       if ($acl->isAllowed($role, $resource, $permission)) {


            return;

        } else {
            $matches->setParam('controller', 'Auth\Controller\User'); // redirect
            $matches->setParam('action', 'accessdenied');

            return;
        }

}

/// rest of the code here

}
Другие вопросы по тегам