嗨,有人可以帮助我防止 bjyauthorize 捕获我引发的 api 事件错误吗?
bjyauthorize 将未登录用户重定向到添加到配置中的登录表单。但是由于我的 api 被允许用于所有角色,即使是来宾,我只希望它返回由 ApiProblemListener 捕获的 Json 错误消息
ApplicationRest\Module.php
class Module implements
ConfigProviderInterface,
AutoloaderProviderInterface
{
public function onBootstrap(MvcEvent $e)
{
$app = $e->getApplication();
$sm = $app->getServiceManager();
$events = $app->getEventManager();
$listener = $sm->get('ApplicationRest\ApiAuthenticationListener');
$events->getSharedManager()->attach('ApplicationRest\Controller', 'dispatch', $listener, 500);
$events->attach('render', array($this, 'onRender'), 100);
$events->attach($sm->get('ApplicationRest\ApiProblemListener'));
}
/**
* Listener for the render event
* Attaches a rendering/response strategy to the View.
*
* @param \Zend\Mvc\MvcEvent $e
*/
public function onRender($e)
{
$result = $e->getResult();
if (!$result instanceof RestfulJsonModel) {
return;
}
//var_dump(123);exit();
$app = $e->getTarget();
$services = $app->getServiceManager();
$view = $services->get('View');
$restfulJsonStrategy = $services->get('ApplicationRest\RestfulJsonStrategy');
$events = $view->getEventManager();
// register at high priority, to "beat" normal json strategy registered
// via view manager
$events->attach($restfulJsonStrategy, 500);
}
}
有很多模块,我真的在考虑将我的 apiModule “ApplicationRest”移到另一个项目,但我真的不想在每次对主项目进行一些更新时更新模型和服务。
欢迎任何建议!谢谢你的时间!
编辑:提供更多 HeaderAuthentication 类
class HeaderAuthentication implements AdapterInterface
{
const AUTHORIZATION_HEADER = 'Authorization';
const CRYPTO = 'sha256';
protected $request;
protected $repository;
public function __construct(RequestInterface $request, UserRepository $repository)
{
$this->request = $request;
$this->repository = $repository;
}
/**
* Authorization: Key={key} Timestamp={timestamp} Signature={signature}
* @return Result
*/
public function authenticate()
{
$request = $this->getRequest();
if (!$request instanceof Request) {
return;
}
$headers = $request->getHeaders();
// Check Authorization header presence
if (!$headers->has(static::AUTHORIZATION_HEADER)) {
return new Result(Result::FAILURE, null, array(
'Authorization header missing'
));
}
$authorization = $headers->get(static::AUTHORIZATION_HEADER)->getFieldValue();
// Validate public key
$publicKey = $this->extractPublicKey($authorization);
$user = $this->getUserRepository()
->findOneByApiSecret($publicKey);
if (null === $user) {
$code = Result::FAILURE_IDENTITY_NOT_FOUND;
return new Result($code, null, array(
'User not found based on public key'
));
}
// Validate signature
$signature = $this->extractSignature($authorization);
/*$hmac = $this->getHmac($request, $user);
if ($signature !== $hmac) {
$code = Result::FAILURE_CREDENTIAL_INVALID;
return new Result($code, null, array(
'Signature does not match'
));
}*/
return new Result(Result::SUCCESS, $user);
}
}
ApiAuthenticationListener
class ApiAuthenticationListener
{
protected $adapter;
public function __construct(HeaderAuthentication $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);
return $response;
}
// All is OK
$event->setParam('user', $result->getIdentity());
}
}