<?php
declare(strict_types=1);
namespace App\EventSubscriber;
use App\Infrastructure\RequestDto\LoginDto;
use App\Infrastructure\Service\Impl\RefreshJwtTokenServiceImpl;
use App\Infrastructure\Service\Impl\VerifyTokenServiceImpl;
use Exception;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Security;
class RefreshTokenSubscriber implements EventSubscriberInterface
{
private Security $security;
private VerifyTokenServiceImpl $verifyAuthToken;
private RefreshJwtTokenServiceImpl $refreshAuthToken;
private RouterInterface $router;
/**
* @param Security $security
* @param VerifyTokenServiceImpl $verifyAuthToken
* @param RefreshJwtTokenServiceImpl $refreshAuthToken
* @param RouterInterface $router
*/
public function __construct(
Security $security,
VerifyTokenServiceImpl $verifyAuthToken,
RefreshJwtTokenServiceImpl $refreshAuthToken,
RouterInterface $router
) {
$this->security = $security;
$this->verifyAuthToken = $verifyAuthToken;
$this->refreshAuthToken = $refreshAuthToken;
$this->router = $router;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => 'refreshToken'
];
}
/**
* @throws Exception
* @return void
*/
public function refreshToken(RequestEvent $request)
{
if ($this->security->getUser() === null) {
return;
}
$jwtToken = $_COOKIE[LoginDto::JWT_TOKEN_COOKIE] ?? null;
if (!$this->verifyAuthToken->isValidToken($jwtToken)) {
$jwtToken = $this->refreshAuthToken->refresh($_COOKIE[LoginDto::JWT_REFRESH_TOKEN_COOKIE]);
if ($jwtToken !== null) {
$this->security->getUser()->setToken($jwtToken);
setcookie(LoginDto::JWT_TOKEN_COOKIE, $jwtToken);
} else {
$request->setResponse(new RedirectResponse($this->router->generate('app_logout')));
}
}
}
}