DoctrineTokenProvider.php 4.7 KB

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