NativeSessionTokenStorage.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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\Security\Csrf\Exception\TokenNotFoundException;
  12. /**
  13. * Token storage that uses PHP's native session handling.
  14. *
  15. * @author Bernhard Schussek <bschussek@gmail.com>
  16. */
  17. class NativeSessionTokenStorage implements ClearableTokenStorageInterface
  18. {
  19. /**
  20. * The namespace used to store values in the session.
  21. */
  22. public const SESSION_NAMESPACE = '_csrf';
  23. private $sessionStarted = false;
  24. private $namespace;
  25. /**
  26. * Initializes the storage with a session namespace.
  27. *
  28. * @param string $namespace The namespace under which the token is stored in the session
  29. */
  30. public function __construct(string $namespace = self::SESSION_NAMESPACE)
  31. {
  32. $this->namespace = $namespace;
  33. }
  34. /**
  35. * {@inheritdoc}
  36. */
  37. public function getToken(string $tokenId)
  38. {
  39. if (!$this->sessionStarted) {
  40. $this->startSession();
  41. }
  42. if (!isset($_SESSION[$this->namespace][$tokenId])) {
  43. throw new TokenNotFoundException('The CSRF token with ID '.$tokenId.' does not exist.');
  44. }
  45. return (string) $_SESSION[$this->namespace][$tokenId];
  46. }
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function setToken(string $tokenId, string $token)
  51. {
  52. if (!$this->sessionStarted) {
  53. $this->startSession();
  54. }
  55. $_SESSION[$this->namespace][$tokenId] = $token;
  56. }
  57. /**
  58. * {@inheritdoc}
  59. */
  60. public function hasToken(string $tokenId)
  61. {
  62. if (!$this->sessionStarted) {
  63. $this->startSession();
  64. }
  65. return isset($_SESSION[$this->namespace][$tokenId]);
  66. }
  67. /**
  68. * {@inheritdoc}
  69. */
  70. public function removeToken(string $tokenId)
  71. {
  72. if (!$this->sessionStarted) {
  73. $this->startSession();
  74. }
  75. if (!isset($_SESSION[$this->namespace][$tokenId])) {
  76. return null;
  77. }
  78. $token = (string) $_SESSION[$this->namespace][$tokenId];
  79. unset($_SESSION[$this->namespace][$tokenId]);
  80. if (!$_SESSION[$this->namespace]) {
  81. unset($_SESSION[$this->namespace]);
  82. }
  83. return $token;
  84. }
  85. /**
  86. * {@inheritdoc}
  87. */
  88. public function clear()
  89. {
  90. unset($_SESSION[$this->namespace]);
  91. }
  92. private function startSession()
  93. {
  94. if (\PHP_SESSION_NONE === session_status()) {
  95. session_start();
  96. }
  97. $this->sessionStarted = true;
  98. }
  99. }