检查 header 特定控制器
check header for a specific controller
我需要检查在访问 BooksController 时是否收到 header 'X-API-User-Name = admin'。
我用这个文档https://symfony.com/doc/current/event_dispatcher/before_after_filters.html
代码
这是我的中间件
namespace App\Event;
use App\Controller\BooksController;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
class HeaderChecker implements EventSubscriberInterface
{
const HEADER = 'X-API-User-Name';
public function onKernelController(ControllerEvent $event): void
{
$controller = $event->getController();
if (is_array($controller)) {
$controller = $controller[0];
}
if ($controller instanceof BooksController) {
$header = $event->getRequest()->headers->has(self::HEADER);
if (!$header) return new JsonResponse(['message' => 'Header X-API-User-Name is not found'], Response::HTTP_FORBIDDEN);
$admin = $event->getRequest()->headers->get(self::HEADER);
if ($admin !== 'admin') return new JsonResponse(['message' => 'Header X-API-User-Name is not valid'], Response::HTTP_FORBIDDEN);
}
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER => 'onKernelController'
];
}
}
service.yaml代码
App\Event\HeaderChecker:
tags:
- { name: kernel.event_subscriber, event: kernel.exception, method: 'onKernelController' }
问题:
通过 var_dump 我检查了数据是否正在输入,但事情是这样的。如果 X-API-User-Name 不是管理员,我需要发送状态为 403 的 JsonResponse。但是如果 X-API-User-Name 不是管理员,我的 EventSubscriber class 不会 return JsonResponse。我的错误是什么?
这里发生了几件事。如果您使用的是 EventSubscriber,那么 services.yaml 中不需要任何额外的行。从评论中我认为你已经明白了。
要验证您的监听器是否正确连接,请使用 bin/console debug:event-dispatcher kernel.controller
。你的听众应该出现。您也可以简单地添加一个转储语句。
清除后,请注意您的 onKernelController 方法有一个 return 类型的 void。你可以 return 任何你想要的,但这不会有什么不同。您 return 的任何内容都将被忽略。这实际上带来了所有这些如何实施的问题?在我看来,查看 HttpKernel::handleRaw 方法非常有启发性。乍一看有点让人不知所措,但它确实显示了内核事件何时触发以及之后发生的事情。
回到如何指示需要 json 响应的问题,RequestEvent 等事件有一个 setResponse 方法。唉,你不知道有请求事件的控制器。
遗憾的是,ControllerEvent 没有 setResponse 方法。相反,它有一个 setController 方法,这意味着您实际上可以更改控制器。
因此您需要执行一个控制器操作,return 是您的 json 响应。然后你使用 $kernel->setController($controller) 来使用它。由于文档中有示例,因此我不会显示详细代码。
有点牵强。可能更容易只检查控制器操作本身中的 headers 并完成它。另一方面,一旦你让它工作并理解它为什么工作,那么你就有了一个对未来非常有用的工具。
最后一个想法:如果这是关于访问控制的,那么你应该抛出一个访问被拒绝的异常。给黑客内部安全信息毫无意义。是否真的存在合法用户无需 header 即可访问此控制器的情况?
我需要检查在访问 BooksController 时是否收到 header 'X-API-User-Name = admin'。
我用这个文档https://symfony.com/doc/current/event_dispatcher/before_after_filters.html
代码 这是我的中间件
namespace App\Event;
use App\Controller\BooksController;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
class HeaderChecker implements EventSubscriberInterface
{
const HEADER = 'X-API-User-Name';
public function onKernelController(ControllerEvent $event): void
{
$controller = $event->getController();
if (is_array($controller)) {
$controller = $controller[0];
}
if ($controller instanceof BooksController) {
$header = $event->getRequest()->headers->has(self::HEADER);
if (!$header) return new JsonResponse(['message' => 'Header X-API-User-Name is not found'], Response::HTTP_FORBIDDEN);
$admin = $event->getRequest()->headers->get(self::HEADER);
if ($admin !== 'admin') return new JsonResponse(['message' => 'Header X-API-User-Name is not valid'], Response::HTTP_FORBIDDEN);
}
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER => 'onKernelController'
];
}
}
service.yaml代码
App\Event\HeaderChecker:
tags:
- { name: kernel.event_subscriber, event: kernel.exception, method: 'onKernelController' }
问题: 通过 var_dump 我检查了数据是否正在输入,但事情是这样的。如果 X-API-User-Name 不是管理员,我需要发送状态为 403 的 JsonResponse。但是如果 X-API-User-Name 不是管理员,我的 EventSubscriber class 不会 return JsonResponse。我的错误是什么?
这里发生了几件事。如果您使用的是 EventSubscriber,那么 services.yaml 中不需要任何额外的行。从评论中我认为你已经明白了。
要验证您的监听器是否正确连接,请使用 bin/console debug:event-dispatcher kernel.controller
。你的听众应该出现。您也可以简单地添加一个转储语句。
清除后,请注意您的 onKernelController 方法有一个 return 类型的 void。你可以 return 任何你想要的,但这不会有什么不同。您 return 的任何内容都将被忽略。这实际上带来了所有这些如何实施的问题?在我看来,查看 HttpKernel::handleRaw 方法非常有启发性。乍一看有点让人不知所措,但它确实显示了内核事件何时触发以及之后发生的事情。
回到如何指示需要 json 响应的问题,RequestEvent 等事件有一个 setResponse 方法。唉,你不知道有请求事件的控制器。
遗憾的是,ControllerEvent 没有 setResponse 方法。相反,它有一个 setController 方法,这意味着您实际上可以更改控制器。
因此您需要执行一个控制器操作,return 是您的 json 响应。然后你使用 $kernel->setController($controller) 来使用它。由于文档中有示例,因此我不会显示详细代码。
有点牵强。可能更容易只检查控制器操作本身中的 headers 并完成它。另一方面,一旦你让它工作并理解它为什么工作,那么你就有了一个对未来非常有用的工具。
最后一个想法:如果这是关于访问控制的,那么你应该抛出一个访问被拒绝的异常。给黑客内部安全信息毫无意义。是否真的存在合法用户无需 header 即可访问此控制器的情况?