src/EventSubscribers/ApiAuthenticationSubscriber.php line 30

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscribers;
  3. use App\Entity\User;
  4. use App\Repository\UserRepository;
  5. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  6. use Symfony\Component\HttpKernel\Event\RequestEvent;
  7. use Symfony\Component\HttpKernel\KernelEvents;
  8. use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
  9. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  10. use Symfony\Component\Security\Core\User\UserInterface;
  11. class ApiAuthenticationSubscriber implements EventSubscriberInterface
  12. {
  13.     private TokenStorageInterface $tokenStorage;
  14.     private UserRepository $userRepository;
  15.     private int $apiDefaultUserId;
  16.     public function __construct(
  17.         TokenStorageInterface $tokenStorage,
  18.         UserRepository $userRepository,
  19.         int $apiDefaultUserId
  20.     ) {
  21.         $this->tokenStorage $tokenStorage;
  22.         $this->userRepository $userRepository;
  23.         $this->apiDefaultUserId $apiDefaultUserId;
  24.     }
  25.     public function onKernelRequest(RequestEvent $event): void
  26.     {
  27.         if (!$event->isMainRequest()) {
  28.             return;
  29.         }
  30.         $request $event->getRequest();
  31.         $path $request->getPathInfo();
  32.         // Проверяем, что запрос начинается с /api/ или /api-test/
  33.         if (strpos($path'/api/') === || strpos($path'/api-test/') === 0) {
  34.             // Если уже есть аутентифицированный пользователь, ничего не делаем
  35.             if ($this->tokenStorage->getToken() && $this->tokenStorage->getToken()->getUser() instanceof UserInterface) {
  36.                 return;
  37.             }
  38.             $user $this->userRepository->find($this->apiDefaultUserId);
  39.             if (!$user instanceof User) {
  40.                 // Пользователь не найден - можно записать в лог, но не прерываем запрос
  41.                 // Бизнес-логика должна обрабатывать отсутствие пользователя
  42.                 return;
  43.             }
  44.             // Создаём токен с ролью
  45.             $token = new PreAuthenticatedToken(
  46.                 $user,
  47.                 'main',
  48.                 'main',
  49.                 $user->getRoles()
  50.             );
  51.             $token->setAuthenticated(true);
  52.             $this->tokenStorage->setToken($token);
  53.         }
  54.     }
  55.     public static function getSubscribedEvents(): array
  56.     {
  57.         return [
  58.             KernelEvents::REQUEST => ['onKernelRequest', -255], // Низкий приоритет: выставляем API-токен после firewall
  59.         ];
  60.     }
  61. }