RefreshToken.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. namespace OAuth2\GrantType;
  3. use OAuth2\Storage\RefreshTokenInterface;
  4. use OAuth2\ResponseType\AccessTokenInterface;
  5. use OAuth2\RequestInterface;
  6. use OAuth2\ResponseInterface;
  7. /**
  8. * @author Brent Shaffer <bshafs at gmail dot com>
  9. */
  10. class RefreshToken implements GrantTypeInterface
  11. {
  12. /**
  13. * @var array
  14. */
  15. private $refreshToken;
  16. /**
  17. * @var RefreshTokenInterface
  18. */
  19. protected $storage;
  20. /**
  21. * @var array
  22. */
  23. protected $config;
  24. /**
  25. * @param RefreshTokenInterface $storage - REQUIRED Storage class for retrieving refresh token information
  26. * @param array $config - OPTIONAL Configuration options for the server
  27. * @code
  28. * $config = array(
  29. * 'always_issue_new_refresh_token' => true, // whether to issue a new refresh token upon successful token request
  30. * 'unset_refresh_token_after_use' => true // whether to unset the refresh token after after using
  31. * );
  32. * @endcode
  33. */
  34. public function __construct(RefreshTokenInterface $storage, $config = array())
  35. {
  36. $this->config = array_merge(array(
  37. 'always_issue_new_refresh_token' => false,
  38. 'unset_refresh_token_after_use' => true
  39. ), $config);
  40. // to preserve B.C. with v1.6
  41. // @see https://github.com/bshaffer/oauth2-server-php/pull/580
  42. // @todo - remove in v2.0
  43. if (isset($config['always_issue_new_refresh_token']) && !isset($config['unset_refresh_token_after_use'])) {
  44. $this->config['unset_refresh_token_after_use'] = $config['always_issue_new_refresh_token'];
  45. }
  46. $this->storage = $storage;
  47. }
  48. /**
  49. * @return string
  50. */
  51. public function getQueryStringIdentifier()
  52. {
  53. return 'refresh_token';
  54. }
  55. /**
  56. * Validate the OAuth request
  57. *
  58. * @param RequestInterface $request
  59. * @param ResponseInterface $response
  60. * @return bool|mixed|null
  61. */
  62. public function validateRequest(RequestInterface $request, ResponseInterface $response)
  63. {
  64. if (!$request->request("refresh_token")) {
  65. $response->setError(400, 'invalid_request', 'Missing parameter: "refresh_token" is required');
  66. return null;
  67. }
  68. if (!$refreshToken = $this->storage->getRefreshToken($request->request("refresh_token"))) {
  69. $response->setError(400, 'invalid_grant', 'Invalid refresh token');
  70. return null;
  71. }
  72. if ($refreshToken['expires'] > 0 && $refreshToken["expires"] < time()) {
  73. $response->setError(400, 'invalid_grant', 'Refresh token has expired');
  74. return null;
  75. }
  76. // store the refresh token locally so we can delete it when a new refresh token is generated
  77. $this->refreshToken = $refreshToken;
  78. return true;
  79. }
  80. /**
  81. * Get client id
  82. *
  83. * @return mixed
  84. */
  85. public function getClientId()
  86. {
  87. return $this->refreshToken['client_id'];
  88. }
  89. /**
  90. * Get user id
  91. *
  92. * @return mixed|null
  93. */
  94. public function getUserId()
  95. {
  96. return isset($this->refreshToken['user_id']) ? $this->refreshToken['user_id'] : null;
  97. }
  98. /**
  99. * Get scope
  100. *
  101. * @return null|string
  102. */
  103. public function getScope()
  104. {
  105. return isset($this->refreshToken['scope']) ? $this->refreshToken['scope'] : null;
  106. }
  107. /**
  108. * Create access token
  109. *
  110. * @param AccessTokenInterface $accessToken
  111. * @param mixed $client_id - client identifier related to the access token.
  112. * @param mixed $user_id - user id associated with the access token
  113. * @param string $scope - scopes to be stored in space-separated string.
  114. * @return array
  115. */
  116. public function createAccessToken(AccessTokenInterface $accessToken, $client_id, $user_id, $scope)
  117. {
  118. /*
  119. * It is optional to force a new refresh token when a refresh token is used.
  120. * However, if a new refresh token is issued, the old one MUST be expired
  121. * @see http://tools.ietf.org/html/rfc6749#section-6
  122. */
  123. $issueNewRefreshToken = $this->config['always_issue_new_refresh_token'];
  124. $unsetRefreshToken = $this->config['unset_refresh_token_after_use'];
  125. $token = $accessToken->createAccessToken($client_id, $user_id, $scope, $issueNewRefreshToken);
  126. if ($unsetRefreshToken) {
  127. $this->storage->unsetRefreshToken($this->refreshToken['refresh_token']);
  128. }
  129. return $token;
  130. }
  131. }