vendor/symfony/symfony/src/Symfony/Component/Security/Csrf/CsrfTokenManager.php line 27

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;
  11. use Symfony\Component\HttpFoundation\RequestStack;
  12. use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
  13. use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
  14. use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
  15. use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage;
  16. use Symfony\Component\Security\Csrf\TokenStorage\TokenStorageInterface;
  17. /**
  18.  * Default implementation of {@link CsrfTokenManagerInterface}.
  19.  *
  20.  * @author Bernhard Schussek <bschussek@gmail.com>
  21.  * @author Kévin Dunglas <dunglas@gmail.com>
  22.  */
  23. class CsrfTokenManager implements CsrfTokenManagerInterface
  24. {
  25.     private $generator;
  26.     private $storage;
  27.     private $namespace;
  28.     /**
  29.      * @param string|RequestStack|callable|null $namespace
  30.      *                                                     * null: generates a namespace using $_SERVER['HTTPS']
  31.      *                                                     * string: uses the given string
  32.      *                                                     * RequestStack: generates a namespace using the current master request
  33.      *                                                     * callable: uses the result of this callable (must return a string)
  34.      */
  35.     public function __construct(TokenGeneratorInterface $generator nullTokenStorageInterface $storage null$namespace null)
  36.     {
  37.         $this->generator $generator ?: new UriSafeTokenGenerator();
  38.         $this->storage $storage ?: new NativeSessionTokenStorage();
  39.         $superGlobalNamespaceGenerator = function () {
  40.             return !empty($_SERVER['HTTPS']) && 'off' !== strtolower($_SERVER['HTTPS']) ? 'https-' '';
  41.         };
  42.         if (null === $namespace) {
  43.             $this->namespace $superGlobalNamespaceGenerator;
  44.         } elseif ($namespace instanceof RequestStack) {
  45.             $this->namespace = function () use ($namespace$superGlobalNamespaceGenerator) {
  46.                 if ($request $namespace->getMasterRequest()) {
  47.                     return $request->isSecure() ? 'https-' '';
  48.                 }
  49.                 return $superGlobalNamespaceGenerator();
  50.             };
  51.         } elseif (\is_callable($namespace) || \is_string($namespace)) {
  52.             $this->namespace $namespace;
  53.         } else {
  54.             throw new InvalidArgumentException(sprintf('$namespace must be a string, a callable returning a string, null or an instance of "RequestStack". "%s" given.', \gettype($namespace)));
  55.         }
  56.     }
  57.     /**
  58.      * {@inheritdoc}
  59.      */
  60.     public function getToken($tokenId)
  61.     {
  62.         $namespacedId $this->getNamespace().$tokenId;
  63.         if ($this->storage->hasToken($namespacedId)) {
  64.             $value $this->storage->getToken($namespacedId);
  65.         } else {
  66.             $value $this->generator->generateToken();
  67.             $this->storage->setToken($namespacedId$value);
  68.         }
  69.         return new CsrfToken($tokenId$value);
  70.     }
  71.     /**
  72.      * {@inheritdoc}
  73.      */
  74.     public function refreshToken($tokenId)
  75.     {
  76.         $namespacedId $this->getNamespace().$tokenId;
  77.         $value $this->generator->generateToken();
  78.         $this->storage->setToken($namespacedId$value);
  79.         return new CsrfToken($tokenId$value);
  80.     }
  81.     /**
  82.      * {@inheritdoc}
  83.      */
  84.     public function removeToken($tokenId)
  85.     {
  86.         return $this->storage->removeToken($this->getNamespace().$tokenId);
  87.     }
  88.     /**
  89.      * {@inheritdoc}
  90.      */
  91.     public function isTokenValid(CsrfToken $token)
  92.     {
  93.         $namespacedId $this->getNamespace().$token->getId();
  94.         if (!$this->storage->hasToken($namespacedId)) {
  95.             return false;
  96.         }
  97.         return hash_equals($this->storage->getToken($namespacedId), $token->getValue());
  98.     }
  99.     private function getNamespace(): string
  100.     {
  101.         return \is_callable($ns $this->namespace) ? $ns() : $ns;
  102.     }
  103. }