我有两个不同的模块。现在我需要为两个模块添加不同的身份验证机制。
所以我添加了事件代码第一个模块&Modules.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的情况下执行的。
我可以在验证之前验证所请求的路由模式,但这看起来像是一个黑客而不是好的解决方案。
如果存在更好的解决方案来处理此问题?
更新: 我的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');
}
}
}
答案 0 :(得分:4)
有一种很好的方法可以使用模块特定的引导程序 - 使用SharedManager
:
$e->getApplication()->getEventManager()->getSharedManager()
->attach(__NAMESPACE__, 'dispatch', function(MvcEvent $e) {
// This code will be executed for all controllers in current __NAMESPACE__
}, 100);
Here是了解EventManager
和SharedEventManager
问题中没有关于听众的其他信息,但我试着猜测:
callable
课程作为听众,那么就可以了,只需用function() { }
替换$listener
即可。 ListenerAggregateInterface
,你应该将听众转换为
SharedListenerAggregateInterface
并使用方法attachAggregate
而不是attach
我希望它有所帮助!