<?php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\Routing\RouterInterface;
class ApiSubscriber implements EventSubscriberInterface
{
private $router;
private $apiPrefix = '/api';
private $apiToken;
public function __construct(RouterInterface $router, string $apiToken)
{
$this->router = $router;
$this->apiToken = $apiToken;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => ['onKernelRequest', 10],
KernelEvents::EXCEPTION => ['onKernelException', 0],
];
}
public function onKernelRequest(RequestEvent $event)
{
$request = $event->getRequest();
if (strpos($request->getPathInfo(), $this->apiPrefix) === 0 && $request->getPathInfo() !== '/api/doc') {
if ($request->isMethod(Request::METHOD_OPTIONS)) {
return;
}
$token = $request->headers->get('X-API-TOKEN');
if ($token !== $this->apiToken) {
$event->setResponse(new JsonResponse([
'error' => 'Invalid or missing API token',
'path' => $request->getPathInfo(),
], Response::HTTP_UNAUTHORIZED));
}
}
}
public function onKernelException(ExceptionEvent $event)
{
$request = $event->getRequest();
if (strpos($request->getPathInfo(), $this->apiPrefix) === 0) {
$exception = $event->getThrowable();
$statusCode = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : Response::HTTP_INTERNAL_SERVER_ERROR;
$event->setResponse(new JsonResponse([
'error' => $exception->getMessage(),
'code' => $statusCode,
], $statusCode));
}
}
}