Blame | Last modification | View Log | RSS feed
<?php/*** Copyright 2017 Facebook, Inc.** You are hereby granted a non-exclusive, worldwide, royalty-free license to* use, copy, modify, and distribute this software in source code or binary* form for use in connection with the web services and APIs provided by* Facebook.** As with any software that integrates with the Facebook platform, your use* of this software is subject to the Facebook Developer Principles and* Policies [http://developers.facebook.com/policy/]. This copyright notice* shall be included in all copies or substantial portions of the software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER* DEALINGS IN THE SOFTWARE.**/namespace Facebook\Authentication;use Facebook\Facebook;use Facebook\FacebookApp;use Facebook\FacebookRequest;use Facebook\FacebookResponse;use Facebook\FacebookClient;use Facebook\Exceptions\FacebookResponseException;use Facebook\Exceptions\FacebookSDKException;/*** Class OAuth2Client** @package Facebook*/class OAuth2Client{/*** @const string The base authorization URL.*/const BASE_AUTHORIZATION_URL = 'https://www.facebook.com';/*** The FacebookApp entity.** @var FacebookApp*/protected $app;/*** The Facebook client.** @var FacebookClient*/protected $client;/*** The version of the Graph API to use.** @var string*/protected $graphVersion;/*** The last request sent to Graph.** @var FacebookRequest|null*/protected $lastRequest;/*** @param FacebookApp $app* @param FacebookClient $client* @param string|null $graphVersion The version of the Graph API to use.*/public function __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null){$this->app = $app;$this->client = $client;$this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION;}/*** Returns the last FacebookRequest that was sent.* Useful for debugging and testing.** @return FacebookRequest|null*/public function getLastRequest(){return $this->lastRequest;}/*** Get the metadata associated with the access token.** @param AccessToken|string $accessToken The access token to debug.** @return AccessTokenMetadata*/public function debugToken($accessToken){$accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken;$params = ['input_token' => $accessToken];$this->lastRequest = new FacebookRequest($this->app,$this->app->getAccessToken(),'GET','/debug_token',$params,null,$this->graphVersion);$response = $this->client->sendRequest($this->lastRequest);$metadata = $response->getDecodedBody();return new AccessTokenMetadata($metadata);}/*** Generates an authorization URL to begin the process of authenticating a user.** @param string $redirectUrl The callback URL to redirect to.* @param string $state The CSPRNG-generated CSRF value.* @param array $scope An array of permissions to request.* @param array $params An array of parameters to generate URL.* @param string $separator The separator to use in http_build_query().** @return string*/public function getAuthorizationUrl($redirectUrl, $state, array $scope = [], array $params = [], $separator = '&'){$params += ['client_id' => $this->app->getId(),'state' => $state,'response_type' => 'code','sdk' => 'php-sdk-' . Facebook::VERSION,'redirect_uri' => $redirectUrl,'scope' => implode(',', $scope)];return static::BASE_AUTHORIZATION_URL . '/' . $this->graphVersion . '/dialog/oauth?' . http_build_query($params, null, $separator);}/*** Get a valid access token from a code.** @param string $code* @param string $redirectUri** @return AccessToken** @throws FacebookSDKException*/public function getAccessTokenFromCode($code, $redirectUri = ''){$params = ['code' => $code,'redirect_uri' => $redirectUri,];return $this->requestAnAccessToken($params);}/*** Exchanges a short-lived access token with a long-lived access token.** @param AccessToken|string $accessToken** @return AccessToken** @throws FacebookSDKException*/public function getLongLivedAccessToken($accessToken){$accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken;$params = ['grant_type' => 'fb_exchange_token','fb_exchange_token' => $accessToken,];return $this->requestAnAccessToken($params);}/*** Get a valid code from an access token.** @param AccessToken|string $accessToken* @param string $redirectUri** @return AccessToken** @throws FacebookSDKException*/public function getCodeFromLongLivedAccessToken($accessToken, $redirectUri = ''){$params = ['redirect_uri' => $redirectUri,];$response = $this->sendRequestWithClientParams('/oauth/client_code', $params, $accessToken);$data = $response->getDecodedBody();if (!isset($data['code'])) {throw new FacebookSDKException('Code was not returned from Graph.', 401);}return $data['code'];}/*** Send a request to the OAuth endpoint.** @param array $params** @return AccessToken** @throws FacebookSDKException*/protected function requestAnAccessToken(array $params){$response = $this->sendRequestWithClientParams('/oauth/access_token', $params);$data = $response->getDecodedBody();if (!isset($data['access_token'])) {throw new FacebookSDKException('Access token was not returned from Graph.', 401);}// Graph returns two different key names for expiration time// on the same endpoint. Doh! :/$expiresAt = 0;if (isset($data['expires'])) {// For exchanging a short lived token with a long lived token.// The expiration time in seconds will be returned as "expires".$expiresAt = time() + $data['expires'];} elseif (isset($data['expires_in'])) {// For exchanging a code for a short lived access token.// The expiration time in seconds will be returned as "expires_in".// See: https://developers.facebook.com/docs/facebook-login/access-tokens#long-via-code$expiresAt = time() + $data['expires_in'];}return new AccessToken($data['access_token'], $expiresAt);}/*** Send a request to Graph with an app access token.** @param string $endpoint* @param array $params* @param AccessToken|string|null $accessToken** @return FacebookResponse** @throws FacebookResponseException*/protected function sendRequestWithClientParams($endpoint, array $params, $accessToken = null){$params += $this->getClientParams();$accessToken = $accessToken ?: $this->app->getAccessToken();$this->lastRequest = new FacebookRequest($this->app,$accessToken,'GET',$endpoint,$params,null,$this->graphVersion);return $this->client->sendRequest($this->lastRequest);}/*** Returns the client_* params for OAuth requests.** @return array*/protected function getClientParams(){return ['client_id' => $this->app->getId(),'client_secret' => $this->app->getSecret(),];}}