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 是一篇了解 EventManager
和 SharedEventManager
之间区别的好文章
问题中没有关于听众的额外信息,但我尝试猜测:
- 如果您使用一些
callable
class 作为监听器 - 没关系,只需将 function() { }
替换为您的 $listener
。
- 如果你使用一些 class 作为监听器,那会实现
ListenerAggregateInterface
,您应该将听众转换为
SharedListenerAggregateInterface
并使用方法 attachAggregate
而不是 attach
希望对您有所帮助!
我有两个不同的模块。现在我需要为两个模块添加不同的身份验证机制。
所以我添加了事件代码第一个模块 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 是一篇了解 EventManager
和 SharedEventManager
问题中没有关于听众的额外信息,但我尝试猜测:
- 如果您使用一些
callable
class 作为监听器 - 没关系,只需将function() { }
替换为您的$listener
。 - 如果你使用一些 class 作为监听器,那会实现
ListenerAggregateInterface
,您应该将听众转换为SharedListenerAggregateInterface
并使用方法attachAggregate
而不是attach
希望对您有所帮助!