vendor/knpuniversity/oauth2-client-bundle/src/Client/OAuth2Client.php line 72
<?php/** OAuth2 Client Bundle* Copyright (c) KnpUniversity <http://knpuniversity.com/>** For the full copyright and license information, please view the LICENSE* file that was distributed with this source code.*/namespace KnpU\OAuth2ClientBundle\Client;use KnpU\OAuth2ClientBundle\Exception\InvalidStateException;use KnpU\OAuth2ClientBundle\Exception\MissingAuthorizationCodeException;use League\OAuth2\Client\Provider\AbstractProvider;use League\OAuth2\Client\Provider\Exception\IdentityProviderException;use League\OAuth2\Client\Token\AccessToken;use Symfony\Component\HttpFoundation\RedirectResponse;use Symfony\Component\HttpFoundation\RequestStack;use Symfony\Component\HttpFoundation\Session\SessionInterface;class OAuth2Client implements OAuth2ClientInterface{public const OAUTH2_SESSION_STATE_KEY = 'knpu.oauth2_client_state';private AbstractProvider $provider;private RequestStack $requestStack;private bool $isStateless = false;/*** OAuth2Client constructor.*/public function __construct(AbstractProvider $provider, RequestStack $requestStack){$this->provider = $provider;$this->requestStack = $requestStack;}/*** Call this to avoid using and checking "state".*/public function setAsStateless(){$this->isStateless = true;}/*** Creates a RedirectResponse that will send the user to the* OAuth2 server (e.g. send them to Facebook).** @param array $scopes The scopes you want (leave empty to use default)* @param array $options Extra options to pass to the Provider's getAuthorizationUrl()* method. For example, <code>scope</code> is a common option.* Generally, these become query parameters when redirecting.** @return RedirectResponse*/public function redirect(array $scopes = [], array $options = []){if (!empty($scopes)) {$options['scope'] = $scopes;}$url = $this->provider->getAuthorizationUrl($options);// set the state (unless we're stateless)if (!$this->isStateless()) {$this->getSession()->set(self::OAUTH2_SESSION_STATE_KEY,$this->provider->getState());}return new RedirectResponse($url);}/*** Call this after the user is redirected back to get the access token.** @param array $options Additional options that should be passed to the getAccessToken() of the underlying provider** @return AccessToken|\League\OAuth2\Client\Token\AccessTokenInterface** @throws InvalidStateException* @throws MissingAuthorizationCodeException* @throws IdentityProviderException If token cannot be fetched*/public function getAccessToken(array $options = []){if (!$this->isStateless()) {$expectedState = $this->getSession()->get(self::OAUTH2_SESSION_STATE_KEY);$actualState = $this->getCurrentRequest()->get('state');if (!$actualState || ($actualState !== $expectedState)) {throw new InvalidStateException('Invalid state');}}$code = $this->getCurrentRequest()->get('code');if (!$code) {throw new MissingAuthorizationCodeException('No "code" parameter was found (usually this is a query parameter)!');}return $this->provider->getAccessToken('authorization_code',array_merge(['code' => $code], $options));}/*** Get a new AccessToken from a refresh token.** @param array $options Additional options that should be passed to the getAccessToken() of the underlying provider** @return AccessToken|\League\OAuth2\Client\Token\AccessTokenInterface** @throws IdentityProviderException If token cannot be fetched*/public function refreshAccessToken(string $refreshToken, array $options = []){return $this->provider->getAccessToken('refresh_token',array_merge(['refresh_token' => $refreshToken], $options));}/*** Returns the "User" information (called a resource owner).** @return \League\OAuth2\Client\Provider\ResourceOwnerInterface*/public function fetchUserFromToken(AccessToken $accessToken){return $this->provider->getResourceOwner($accessToken);}/*** Shortcut to fetch the access token and user all at once.** Only use this if you don't need the access token, but only* need the user.** @return \League\OAuth2\Client\Provider\ResourceOwnerInterface*/public function fetchUser(){/** @var AccessToken $token */$token = $this->getAccessToken();return $this->fetchUserFromToken($token);}/*** Returns the underlying OAuth2 provider.** @return AbstractProvider*/public function getOAuth2Provider(){return $this->provider;}protected function isStateless(): bool{return $this->isStateless;}/*** @return \Symfony\Component\HttpFoundation\Request*/private function getCurrentRequest(){$request = $this->requestStack->getCurrentRequest();if (!$request) {throw new \LogicException('There is no "current request", and it is needed to perform this action');}return $request;}/*** @return SessionInterface*/private function getSession(){if (!$this->getCurrentRequest()->hasSession()) {throw new \LogicException('In order to use "state", you must have a session. Set the OAuth2Client to stateless to avoid state');}return $this->getCurrentRequest()->getSession();}}