vendor/symfony/security-http/RememberMe/AbstractRememberMeHandler.php line 31

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.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 Symfony\Component\Security\Http\RememberMe;
  11. use Psr\Log\LoggerInterface;
  12. use Symfony\Component\HttpFoundation\Cookie;
  13. use Symfony\Component\HttpFoundation\RequestStack;
  14. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  15. use Symfony\Component\Security\Core\User\UserInterface;
  16. use Symfony\Component\Security\Core\User\UserProviderInterface;
  17. /**
  18.  * @author Wouter de Jong <wouter@wouterj.nl>
  19.  */
  20. abstract class AbstractRememberMeHandler implements RememberMeHandlerInterface
  21. {
  22.     private UserProviderInterface $userProvider;
  23.     protected $requestStack;
  24.     protected $options;
  25.     protected $logger;
  26.     public function __construct(UserProviderInterface $userProviderRequestStack $requestStack, array $options = [], LoggerInterface $logger null)
  27.     {
  28.         $this->userProvider $userProvider;
  29.         $this->requestStack $requestStack;
  30.         $this->options $options + [
  31.             'name' => 'REMEMBERME',
  32.             'lifetime' => 31536000,
  33.             'path' => '/',
  34.             'domain' => null,
  35.             'secure' => false,
  36.             'httponly' => true,
  37.             'samesite' => null,
  38.             'always_remember_me' => false,
  39.             'remember_me_parameter' => '_remember_me',
  40.         ];
  41.         $this->logger $logger;
  42.     }
  43.     /**
  44.      * Checks if the RememberMeDetails is a valid cookie to login the given User.
  45.      *
  46.      * This method should also:
  47.      * - Create a new remember-me cookie to be sent with the response (using {@see createCookie()});
  48.      * - If you store the token somewhere else (e.g. in a database), invalidate the stored token.
  49.      *
  50.      * @throws AuthenticationException If the remember-me details are not accepted
  51.      */
  52.     abstract protected function processRememberMe(RememberMeDetails $rememberMeDetailsUserInterface $user): void;
  53.     /**
  54.      * {@inheritdoc}
  55.      */
  56.     public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): UserInterface
  57.     {
  58.         try {
  59.             $user $this->userProvider->loadUserByIdentifier($rememberMeDetails->getUserIdentifier());
  60.         } catch (AuthenticationException $e) {
  61.             throw $e;
  62.         }
  63.         if (!$user instanceof UserInterface) {
  64.             throw new \LogicException(sprintf('The UserProviderInterface implementation must return an instance of UserInterface, but returned "%s".'get_debug_type($user)));
  65.         }
  66.         $this->processRememberMe($rememberMeDetails$user);
  67.         $this->logger?->info('Remember-me cookie accepted.');
  68.         return $user;
  69.     }
  70.     /**
  71.      * {@inheritdoc}
  72.      */
  73.     public function clearRememberMeCookie(): void
  74.     {
  75.         $this->logger?->debug('Clearing remember-me cookie.', ['name' => $this->options['name']]);
  76.         $this->createCookie(null);
  77.     }
  78.     /**
  79.      * Creates the remember-me cookie using the correct configuration.
  80.      *
  81.      * @param RememberMeDetails|null $rememberMeDetails The details for the cookie, or null to clear the remember-me cookie
  82.      */
  83.     protected function createCookie(?RememberMeDetails $rememberMeDetails)
  84.     {
  85.         $request $this->requestStack->getMainRequest();
  86.         if (!$request) {
  87.             throw new \LogicException('Cannot create the remember-me cookie; no master request available.');
  88.         }
  89.         // the ResponseListener configures the cookie saved in this attribute on the final response object
  90.         $request->attributes->set(ResponseListener::COOKIE_ATTR_NAME, new Cookie(
  91.             $this->options['name'],
  92.             $rememberMeDetails?->toString(),
  93.             $rememberMeDetails?->getExpires() ?? 1,
  94.             $this->options['path'],
  95.             $this->options['domain'],
  96.             $this->options['secure'] ?? $request->isSecure(),
  97.             $this->options['httponly'],
  98.             false,
  99.             $this->options['samesite']
  100.         ));
  101.     }
  102. }