Zend framework 2:为两个不同的模块添加不同的身份验证适配器

Zend framework 2 : Add different authentication adapter for two different modules

我有两个不同的模块。现在我需要为两个模块添加不同的身份验证机制。

所以我添加了事件代码第一个模块 Module.php 的 onBootstrap 方法

$listener = $serviceManager->get('First\Service\AuthListener');
$listener->setAdapter($serviceManager->get('First\Service\BasicAuthAdapter'));
$eventManager->attach(MvcEvent::EVENT_ROUTE, $listener, 0);

并且在第二个模块 Module.php 的 onBootstrap 方法中

$listener = $serviceManager->get('Second\Service\AuthListener');
$listener->setAdapter($serviceManager->get('Second\Service\AdvAuthAdapter'));
$eventManager->attach(MvcEvent::EVENT_ROUTE, $listener, 0);

现在,如果我禁用其中一个模块,功能可以正常工作并请求正确验证。虽然启用两个模块做某种重叠所以即使要求模块正确验证,但其他模块事件代码也得到执行并且系统给出未验证错误。

我认为这是因为 module.php 中的事件处理程序代码在执行时没有处理请求的模块 url。

我可以在身份验证之前使用请求的路由模式进行验证,但这看起来像是一个 hack 而不是好的解决方案。

是否存在更好的解决方案来处理此问题?

更新: 我的 AuthListener 代码:

namespace First\Service;
use Zend\Authentication\Adapter\AdapterInterface;
use Zend\Mvc\MvcEvent;

class AuthListener
{
    protected $adapter;

    public function setAdapter(AdapterInterface $adapter)
    {
        $this->adapter = $adapter;
    }

    public function __invoke(MvcEvent $event)
    {
        $result = $this->adapter->authenticate();

        if (!$result->isValid()) {

            $response = $event->getResponse();

            // Set some response content
            $response->setStatusCode(401);

            $routeMatch = $event->getRouteMatch();
            $routeMatch->setParam('controller', 'First\Controller\Error');
            $routeMatch->setParam('action', 'Auth');
        }
    }
}

有一个使模块特定的好方法 bootstrap - 使用 SharedManager:

$e->getApplication()->getEventManager()->getSharedManager()
  ->attach(__NAMESPACE__, 'dispatch', function(MvcEvent $e) {

     // This code will be executed for all controllers in current __NAMESPACE__

}, 100);

Here 是一篇了解 EventManagerSharedEventManager

之间区别的好文章

问题中没有关于听众的额外信息,但我尝试猜测:

  • 如果您使用一些 callable class 作为监听器 - 没关系,只需将 function() { } 替换为您的 $listener
  • 如果你使用一些 class 作为监听器,那会实现 ListenerAggregateInterface,您应该将听众转换为 SharedListenerAggregateInterface 并使用方法 attachAggregate 而不是 attach

希望对您有所帮助!