vendor/gesdinet/jwt-refresh-token-bundle/EventListener/AttachRefreshTokenOnSuccessListener.php line 109

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the GesdinetJWTRefreshTokenBundle package.
  4.  *
  5.  * (c) Gesdinet <http://www.gesdinet.com/>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Gesdinet\JWTRefreshTokenBundle\EventListener;
  11. use Gesdinet\JWTRefreshTokenBundle\Generator\RefreshTokenGeneratorInterface;
  12. use Gesdinet\JWTRefreshTokenBundle\Model\RefreshTokenInterface;
  13. use Gesdinet\JWTRefreshTokenBundle\Model\RefreshTokenManagerInterface;
  14. use Gesdinet\JWTRefreshTokenBundle\Request\Extractor\ExtractorInterface;
  15. use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
  16. use Symfony\Component\HttpFoundation\Cookie;
  17. use Symfony\Component\Security\Core\User\UserInterface;
  18. use Symfony\Component\HttpFoundation\RequestStack;
  19. use Symfony\Component\HttpKernel\Kernel;
  20. class AttachRefreshTokenOnSuccessListener
  21. {
  22.     /**
  23.      * @var RefreshTokenManagerInterface
  24.      */
  25.     protected $refreshTokenManager;
  26.     /**
  27.      * @var int
  28.      */
  29.     protected $ttl;
  30.     /**
  31.      * @var RequestStack
  32.      */
  33.     protected $requestStack;
  34.     /**
  35.      * @var string
  36.      */
  37.     protected $tokenParameterName;
  38.     /**
  39.      * @var bool
  40.      */
  41.     protected $singleUse;
  42.     /**
  43.      * @var RefreshTokenGeneratorInterface
  44.      */
  45.     protected $refreshTokenGenerator;
  46.     /**
  47.      * @var ExtractorInterface
  48.      */
  49.     protected $extractor;
  50.     protected array $cookieSettings;
  51.     protected bool $returnExpiration;
  52.     protected string $returnExpirationParameterName;
  53.     /**
  54.      * @param int    $ttl
  55.      * @param string $tokenParameterName
  56.      * @param bool   $singleUse
  57.      */
  58.     public function __construct(
  59.         RefreshTokenManagerInterface $refreshTokenManager,
  60.         $ttl,
  61.         RequestStack $requestStack,
  62.         $tokenParameterName,
  63.         $singleUse,
  64.         RefreshTokenGeneratorInterface $refreshTokenGenerator,
  65.         ExtractorInterface $extractor,
  66.         array $cookieSettings,
  67.         bool $returnExpiration false,
  68.         string $returnExpirationParameterName 'refresh_token_expiration'
  69.     ) {
  70.         $this->refreshTokenManager $refreshTokenManager;
  71.         $this->ttl $ttl;
  72.         $this->requestStack $requestStack;
  73.         $this->tokenParameterName $tokenParameterName;
  74.         $this->singleUse $singleUse;
  75.         $this->refreshTokenGenerator $refreshTokenGenerator;
  76.         $this->extractor $extractor;
  77.         $this->cookieSettings array_merge([
  78.             'enabled' => false,
  79.             'same_site' => 'lax',
  80.             'path' => '/',
  81.             'domain' => null,
  82.             'http_only' => true,
  83.             'secure' => true,
  84.             'remove_token_from_body' => true,
  85.             'partitioned' => false,
  86.         ], $cookieSettings);
  87.         $this->returnExpiration $returnExpiration;
  88.         $this->returnExpirationParameterName $returnExpirationParameterName;
  89.         if ($this->cookieSettings['partitioned'] && Kernel::VERSION '6.4') {
  90.             throw new \LogicException(sprintf('The `partitioned` option for cookies is only available for Symfony 6.4 and above. You are currently on version %s'Kernel::VERSION));
  91.         }
  92.     }
  93.     public function attachRefreshToken(AuthenticationSuccessEvent $event): void
  94.     {
  95.         $user $event->getUser();
  96.         if (!$user instanceof UserInterface) {
  97.             return;
  98.         }
  99.         $data $event->getData();
  100.         $request $this->requestStack->getCurrentRequest();
  101.         if (null === $request) {
  102.             return;
  103.         }
  104.         // Extract refreshToken from the request
  105.         $refreshTokenString $this->extractor->getRefreshToken($request$this->tokenParameterName);
  106.         // Remove the current refreshToken if it is single-use
  107.         if ($refreshTokenString && true === $this->singleUse) {
  108.             $refreshToken $this->refreshTokenManager->get($refreshTokenString);
  109.             $refreshTokenString null;
  110.             if ($refreshToken instanceof RefreshTokenInterface) {
  111.                 $this->refreshTokenManager->delete($refreshToken);
  112.             }
  113.         }
  114.         // Set or create the refreshTokenString
  115.         if ($refreshTokenString) {
  116.             $data[$this->tokenParameterName] = $refreshTokenString;
  117.             if ($this->returnExpiration) {
  118.                 $refreshToken $this->refreshTokenManager->get($refreshTokenString);
  119.                 $data[$this->returnExpirationParameterName] = ($refreshToken) ? $refreshToken->getValid()->getTimestamp() : 0;
  120.             }
  121.         } else {
  122.             $refreshToken $this->refreshTokenGenerator->createForUserWithTtl($user$this->ttl);
  123.             $this->refreshTokenManager->save($refreshToken);
  124.             $refreshTokenString $refreshToken->getRefreshToken();
  125.             $data[$this->tokenParameterName] = $refreshTokenString;
  126.             if ($this->returnExpiration) {
  127.                 $data[$this->returnExpirationParameterName] = $refreshToken->getValid()->getTimestamp();
  128.             }
  129.         }
  130.         // Add a response cookie if enabled
  131.         if ($this->cookieSettings['enabled']) {
  132.             $event->getResponse()->headers->setCookie(
  133.                 new Cookie(
  134.                     $this->tokenParameterName,
  135.                     $refreshTokenString,
  136.                     time() + $this->ttl,
  137.                     $this->cookieSettings['path'],
  138.                     $this->cookieSettings['domain'],
  139.                     $this->cookieSettings['secure'],
  140.                     $this->cookieSettings['http_only'],
  141.                     false,
  142.                     $this->cookieSettings['same_site'],
  143.                     $this->cookieSettings['partitioned'],
  144.                 )
  145.             );
  146.             // Remove the refreshTokenString from the response body
  147.             if (isset($this->cookieSettings['remove_token_from_body']) && $this->cookieSettings['remove_token_from_body']) {
  148.                 unset($data[$this->tokenParameterName]);
  149.             }
  150.         }
  151.         // Set response data
  152.         $event->setData($data);
  153.     }
  154. }