vendor/symfony/symfony/src/Symfony/Component/Security/Csrf/TokenStorage/SessionTokenStorage.php line 75

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\Csrf\TokenStorage;
  11. use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpFoundation\RequestStack;
  14. use Symfony\Component\HttpFoundation\Session\Session;
  15. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  16. use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
  17. use Symfony\Component\Security\Csrf\Exception\TokenNotFoundException;
  18. /**
  19.  * Token storage that uses a Symfony Session object.
  20.  *
  21.  * @author Bernhard Schussek <bschussek@gmail.com>
  22.  */
  23. class SessionTokenStorage implements ClearableTokenStorageInterface
  24. {
  25.     /**
  26.      * The namespace used to store values in the session.
  27.      */
  28.     public const SESSION_NAMESPACE '_csrf';
  29.     private $requestStack;
  30.     private $namespace;
  31.     /**
  32.      * To be removed in Symfony 6.0.
  33.      */
  34.     private $session;
  35.     /**
  36.      * Initializes the storage with a RequestStack object and a session namespace.
  37.      *
  38.      * @param RequestStack $requestStack
  39.      * @param string       $namespace    The namespace under which the token is stored in the requestStack
  40.      */
  41.     public function __construct(/* RequestStack */ $requestStackstring $namespace self::SESSION_NAMESPACE)
  42.     {
  43.         if ($requestStack instanceof SessionInterface) {
  44.             trigger_deprecation('symfony/security-csrf''5.3''Passing a "%s" to "%s" is deprecated, use a "%s" instead.'SessionInterface::class, __CLASS__RequestStack::class);
  45.             $request = new Request();
  46.             $request->setSession($requestStack);
  47.             $requestStack = new RequestStack();
  48.             $requestStack->push($request);
  49.         }
  50.         $this->requestStack $requestStack;
  51.         $this->namespace $namespace;
  52.     }
  53.     /**
  54.      * {@inheritdoc}
  55.      */
  56.     public function getToken(string $tokenId)
  57.     {
  58.         $session $this->getSession();
  59.         if (!$session->isStarted()) {
  60.             $session->start();
  61.         }
  62.         if (!$session->has($this->namespace.'/'.$tokenId)) {
  63.             throw new TokenNotFoundException('The CSRF token with ID '.$tokenId.' does not exist.');
  64.         }
  65.         return (string) $session->get($this->namespace.'/'.$tokenId);
  66.     }
  67.     /**
  68.      * {@inheritdoc}
  69.      */
  70.     public function setToken(string $tokenIdstring $token)
  71.     {
  72.         $session $this->getSession();
  73.         if (!$session->isStarted()) {
  74.             $session->start();
  75.         }
  76.         $session->set($this->namespace.'/'.$tokenId$token);
  77.     }
  78.     /**
  79.      * {@inheritdoc}
  80.      */
  81.     public function hasToken(string $tokenId)
  82.     {
  83.         $session $this->getSession();
  84.         if (!$session->isStarted()) {
  85.             $session->start();
  86.         }
  87.         return $session->has($this->namespace.'/'.$tokenId);
  88.     }
  89.     /**
  90.      * {@inheritdoc}
  91.      */
  92.     public function removeToken(string $tokenId)
  93.     {
  94.         $session $this->getSession();
  95.         if (!$session->isStarted()) {
  96.             $session->start();
  97.         }
  98.         return $session->remove($this->namespace.'/'.$tokenId);
  99.     }
  100.     /**
  101.      * {@inheritdoc}
  102.      */
  103.     public function clear()
  104.     {
  105.         $session $this->getSession();
  106.         foreach (array_keys($session->all()) as $key) {
  107.             if (str_starts_with($key$this->namespace.'/')) {
  108.                 $session->remove($key);
  109.             }
  110.         }
  111.     }
  112.     private function getSession(): SessionInterface
  113.     {
  114.         try {
  115.             return $this->session ?? $this->requestStack->getSession();
  116.         } catch (SessionNotFoundException $e) {
  117.             trigger_deprecation('symfony/security-csrf''5.3''Using the "%s" without a session has no effect and is deprecated. It will throw a "%s" in Symfony 6.0'__CLASS__SessionNotFoundException::class);
  118.             return $this->session ?? $this->session = new Session(new MockArraySessionStorage());
  119.         }
  120.     }
  121. }