<?php
namespace App\EventSubscribers;
use App\Entity\User;
use App\Repository\UserRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\User\UserInterface;
class ApiAuthenticationSubscriber implements EventSubscriberInterface
{
private TokenStorageInterface $tokenStorage;
private UserRepository $userRepository;
private int $apiDefaultUserId;
public function __construct(
TokenStorageInterface $tokenStorage,
UserRepository $userRepository,
int $apiDefaultUserId
) {
$this->tokenStorage = $tokenStorage;
$this->userRepository = $userRepository;
$this->apiDefaultUserId = $apiDefaultUserId;
}
public function onKernelRequest(RequestEvent $event): void
{
if (!$event->isMainRequest()) {
return;
}
$request = $event->getRequest();
$path = $request->getPathInfo();
// Проверяем, что запрос начинается с /api/ или /api-test/
if (strpos($path, '/api/') === 0 || strpos($path, '/api-test/') === 0) {
// Если уже есть аутентифицированный пользователь, ничего не делаем
if ($this->tokenStorage->getToken() && $this->tokenStorage->getToken()->getUser() instanceof UserInterface) {
return;
}
$user = $this->userRepository->find($this->apiDefaultUserId);
if (!$user instanceof User) {
// Пользователь не найден - можно записать в лог, но не прерываем запрос
// Бизнес-логика должна обрабатывать отсутствие пользователя
return;
}
// Создаём токен с ролью
$token = new PreAuthenticatedToken(
$user,
'main',
$user->getRoles()
);
$token->setAuthenticated(true);
$this->tokenStorage->setToken($token);
}
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['onKernelRequest', 255], // Высокий приоритет
];
}
}