DoctrineTokenProvider.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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\Bridge\Doctrine\Security\RememberMe;
  11. use Doctrine\DBAL\Connection;
  12. use Doctrine\DBAL\Types\Type as DoctrineType;
  13. use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken;
  14. use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentTokenInterface;
  15. use Symfony\Component\Security\Core\Authentication\RememberMe\TokenProviderInterface;
  16. use Symfony\Component\Security\Core\Exception\TokenNotFoundException;
  17. /**
  18. * This class provides storage for the tokens that is set in "remember me"
  19. * cookies. This way no password secrets will be stored in the cookies on
  20. * the client machine, and thus the security is improved.
  21. *
  22. * This depends only on doctrine in order to get a database connection
  23. * and to do the conversion of the datetime column.
  24. *
  25. * In order to use this class, you need the following table in your database:
  26. *
  27. * CREATE TABLE `rememberme_token` (
  28. * `series` char(88) UNIQUE PRIMARY KEY NOT NULL,
  29. * `value` char(88) NOT NULL,
  30. * `lastUsed` datetime NOT NULL,
  31. * `class` varchar(100) NOT NULL,
  32. * `username` varchar(200) NOT NULL
  33. * );
  34. */
  35. class DoctrineTokenProvider implements TokenProviderInterface
  36. {
  37. private $conn;
  38. public function __construct(Connection $conn)
  39. {
  40. $this->conn = $conn;
  41. }
  42. /**
  43. * {@inheritdoc}
  44. */
  45. public function loadTokenBySeries($series)
  46. {
  47. // the alias for lastUsed works around case insensitivity in PostgreSQL
  48. $sql = 'SELECT class, username, value, lastUsed AS last_used'
  49. .' FROM rememberme_token WHERE series=:series';
  50. $paramValues = array('series' => $series);
  51. $paramTypes = array('series' => \PDO::PARAM_STR);
  52. $stmt = $this->conn->executeQuery($sql, $paramValues, $paramTypes);
  53. $row = $stmt->fetch(\PDO::FETCH_ASSOC);
  54. if ($row) {
  55. return new PersistentToken($row['class'], $row['username'], $series, $row['value'], new \DateTime($row['last_used']));
  56. }
  57. throw new TokenNotFoundException('No token found.');
  58. }
  59. /**
  60. * {@inheritdoc}
  61. */
  62. public function deleteTokenBySeries($series)
  63. {
  64. $sql = 'DELETE FROM rememberme_token WHERE series=:series';
  65. $paramValues = array('series' => $series);
  66. $paramTypes = array('series' => \PDO::PARAM_STR);
  67. $this->conn->executeUpdate($sql, $paramValues, $paramTypes);
  68. }
  69. /**
  70. * {@inheritdoc}
  71. */
  72. public function updateToken($series, $tokenValue, \DateTime $lastUsed)
  73. {
  74. $sql = 'UPDATE rememberme_token SET value=:value, lastUsed=:lastUsed'
  75. .' WHERE series=:series';
  76. $paramValues = array(
  77. 'value' => $tokenValue,
  78. 'lastUsed' => $lastUsed,
  79. 'series' => $series,
  80. );
  81. $paramTypes = array(
  82. 'value' => \PDO::PARAM_STR,
  83. 'lastUsed' => DoctrineType::DATETIME,
  84. 'series' => \PDO::PARAM_STR,
  85. );
  86. $updated = $this->conn->executeUpdate($sql, $paramValues, $paramTypes);
  87. if ($updated < 1) {
  88. throw new TokenNotFoundException('No token found.');
  89. }
  90. }
  91. /**
  92. * {@inheritdoc}
  93. */
  94. public function createNewToken(PersistentTokenInterface $token)
  95. {
  96. $sql = 'INSERT INTO rememberme_token'
  97. .' (class, username, series, value, lastUsed)'
  98. .' VALUES (:class, :username, :series, :value, :lastUsed)';
  99. $paramValues = array(
  100. 'class' => $token->getClass(),
  101. 'username' => $token->getUsername(),
  102. 'series' => $token->getSeries(),
  103. 'value' => $token->getTokenValue(),
  104. 'lastUsed' => $token->getLastUsed(),
  105. );
  106. $paramTypes = array(
  107. 'class' => \PDO::PARAM_STR,
  108. 'username' => \PDO::PARAM_STR,
  109. 'series' => \PDO::PARAM_STR,
  110. 'value' => \PDO::PARAM_STR,
  111. 'lastUsed' => DoctrineType::DATETIME,
  112. );
  113. $this->conn->executeUpdate($sql, $paramValues, $paramTypes);
  114. }
  115. }