vendor/league/oauth2-server/src/Grant/RefreshTokenGrant.php line 79

  1. <?php
  2. /**
  3.  * OAuth 2.0 Refresh token grant.
  4.  *
  5.  * @author      Alex Bilbie <hello@alexbilbie.com>
  6.  * @copyright   Copyright (c) Alex Bilbie
  7.  * @license     http://mit-license.org/
  8.  *
  9.  * @link        https://github.com/thephpleague/oauth2-server
  10.  */
  11. namespace League\OAuth2\Server\Grant;
  12. use DateInterval;
  13. use Exception;
  14. use League\OAuth2\Server\Exception\OAuthServerException;
  15. use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
  16. use League\OAuth2\Server\RequestAccessTokenEvent;
  17. use League\OAuth2\Server\RequestEvent;
  18. use League\OAuth2\Server\RequestRefreshTokenEvent;
  19. use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
  20. use Psr\Http\Message\ServerRequestInterface;
  21. /**
  22.  * Refresh token grant.
  23.  */
  24. class RefreshTokenGrant extends AbstractGrant
  25. {
  26.     /**
  27.      * @param RefreshTokenRepositoryInterface $refreshTokenRepository
  28.      */
  29.     public function __construct(RefreshTokenRepositoryInterface $refreshTokenRepository)
  30.     {
  31.         $this->setRefreshTokenRepository($refreshTokenRepository);
  32.         $this->refreshTokenTTL = new DateInterval('P1M');
  33.     }
  34.     /**
  35.      * {@inheritdoc}
  36.      */
  37.     public function respondToAccessTokenRequest(
  38.         ServerRequestInterface $request,
  39.         ResponseTypeInterface $responseType,
  40.         DateInterval $accessTokenTTL
  41.     ) {
  42.         // Validate request
  43.         $client $this->validateClient($request);
  44.         $oldRefreshToken $this->validateOldRefreshToken($request$client->getIdentifier());
  45.         $scopes $this->validateScopes(
  46.             $this->getRequestParameter(
  47.                 'scope',
  48.                 $request,
  49.                 \implode(self::SCOPE_DELIMITER_STRING$oldRefreshToken['scopes'])
  50.             )
  51.         );
  52.         // The OAuth spec says that a refreshed access token can have the original scopes or fewer so ensure
  53.         // the request doesn't include any new scopes
  54.         foreach ($scopes as $scope) {
  55.             if (\in_array($scope->getIdentifier(), $oldRefreshToken['scopes'], true) === false) {
  56.                 throw OAuthServerException::invalidScope($scope->getIdentifier());
  57.             }
  58.         }
  59.         // Expire old tokens
  60.         $this->accessTokenRepository->revokeAccessToken($oldRefreshToken['access_token_id']);
  61.         if ($this->revokeRefreshTokens) {
  62.             $this->refreshTokenRepository->revokeRefreshToken($oldRefreshToken['refresh_token_id']);
  63.         }
  64.         // Issue and persist new access token
  65.         $accessToken $this->issueAccessToken($accessTokenTTL$client$oldRefreshToken['user_id'], $scopes);
  66.         $this->getEmitter()->emit(new RequestAccessTokenEvent(RequestEvent::ACCESS_TOKEN_ISSUED$request$accessToken));
  67.         $responseType->setAccessToken($accessToken);
  68.         // Issue and persist new refresh token if given
  69.         if ($this->revokeRefreshTokens) {
  70.             $refreshToken $this->issueRefreshToken($accessToken);
  71.             if ($refreshToken !== null) {
  72.                 $this->getEmitter()->emit(new RequestRefreshTokenEvent(RequestEvent::REFRESH_TOKEN_ISSUED$request$refreshToken));
  73.                 $responseType->setRefreshToken($refreshToken);
  74.             }
  75.         }
  76.         return $responseType;
  77.     }
  78.     /**
  79.      * @param ServerRequestInterface $request
  80.      * @param string                 $clientId
  81.      *
  82.      * @throws OAuthServerException
  83.      *
  84.      * @return array
  85.      */
  86.     protected function validateOldRefreshToken(ServerRequestInterface $request$clientId)
  87.     {
  88.         $encryptedRefreshToken $this->getRequestParameter('refresh_token'$request);
  89.         if (!\is_string($encryptedRefreshToken)) {
  90.             throw OAuthServerException::invalidRequest('refresh_token');
  91.         }
  92.         // Validate refresh token
  93.         try {
  94.             $refreshToken $this->decrypt($encryptedRefreshToken);
  95.         } catch (Exception $e) {
  96.             throw OAuthServerException::invalidRefreshToken('Cannot decrypt the refresh token'$e);
  97.         }
  98.         $refreshTokenData \json_decode($refreshTokentrue);
  99.         if ($refreshTokenData['client_id'] !== $clientId) {
  100.             $this->getEmitter()->emit(new RequestEvent(RequestEvent::REFRESH_TOKEN_CLIENT_FAILED$request));
  101.             throw OAuthServerException::invalidRefreshToken('Token is not linked to client');
  102.         }
  103.         if ($refreshTokenData['expire_time'] < \time()) {
  104.             throw OAuthServerException::invalidRefreshToken('Token has expired');
  105.         }
  106.         if ($this->refreshTokenRepository->isRefreshTokenRevoked($refreshTokenData['refresh_token_id']) === true) {
  107.             throw OAuthServerException::invalidRefreshToken('Token has been revoked');
  108.         }
  109.         return $refreshTokenData;
  110.     }
  111.     /**
  112.      * {@inheritdoc}
  113.      */
  114.     public function getIdentifier()
  115.     {
  116.         return 'refresh_token';
  117.     }
  118. }