私はリスナー集約の例があります。
違いは、リダイレクトが発生するかどうかを判断するために、リスナーが設定と一致するルート名を使用する点です。 dispatch.error
の間に、$mvcEvent->getParam('exception')
を使用してMVCイベントから例外をフェッチして確認することができます。
use ArpAuth\Service\AuthenticationService;
use ArpAuth\Service\AuthenticationServiceAwareTrait;
use Zend\Console\Console;
use Zend\EventManager\EventManagerInterface;
use Zend\Http\Response;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\RouteMatch;
use Zend\EventManager\AbstractListenerAggregate;
class NoAuthRedirectStrategy extends AbstractListenerAggregate
{
protected $whitelistRoutes = [];
protected $redirectRoute = 'user/auth/login';
use AuthenticationServiceAwareTrait;
public function __construct(AuthenticationService $authenticationService, array $options = [])
{
$this->authenticationService = $authenticationService;
if (! empty($options)) {
$this->setOptions($options);
}
}
public function attach(EventManagerInterface $eventManager)
{
$eventManager->attach(MvcEvent::EVENT_DISPATCH, [$this, 'isAuthenticated'], 1000);
}
public function isAuthenticated(MvcEvent $event)
{
$routeMatch = $event->getRouteMatch();
if (Console::isConsole() || ! $routeMatch instanceof RouteMatch) {
return;
}
$serviceManager = $event->getApplication()->getServiceManager();
$currentRoute = $routeMatch->getMatchedRouteName();
$isRemoteApiCall = $serviceManager->get('IsRemoteApiCall');
if ($this->hasWhitelistRoute($currentRoute) || $isRemoteApiCall || $this->authenticationService->hasIdentity()) {
return;
}
$router = $event->getRouter();
/** @var Response $response */
$response = $event->getResponse();
$url = $router->assemble([], ['name' => $this->redirectRoute]);
$response->getHeaders()->addHeaderLine('Location', $url);
$response->setStatusCode(302);
return $response;
}
public function setRedirectRoute($redirectRoute)
{
$this->redirectRoute = $redirectRoute;
return $this;
}
public function hasWhitelistRoute($route)
{
return (! empty($route) && in_array($route, $this->whitelistRoutes));
}
public function getWhitelistRoutes()
{
return $this->whitelistRoutes;
}
public function setWhitelistRoutes(array $routes)
{
$this->whitelistRoutes = [];
return $this->addWhitelistRoutes($routes);
}
public function addWhitelistRoutes(array $routes)
{
foreach($routes as $route) {
$this->addWhitelistRoute($route);
}
return $this;
}
public function addWhitelistRoute($route)
{
if (! $this->hasWhiteListRoute($route)) {
$this->whitelistRoutes[] = $route;
}
return $this;
}
public function setOptions(array $options)
{
if (isset($options['whitelist']) && is_array($options['whitelist'])) {
$this->setWhitelistRoutes($options['whitelist']);
}
if (isset($options['redirect_route'])) {
$this->setRedirectRoute($options['redirect_route']);
}
return $this;
}
}
ありがとう。 「例外」がイベントパラメータであったことはどうでしたか?それは本当に役に立ちます。 –
@kimディスパッチコントローラのメインイベントリスナーである[ディスパッチリスナ](https://github.com/zendframework/zend-mvc/blob/master/src/DispatchListener.php#L131)を確認してください。 – AlexP