Вход Регистрация
Файл: social_login/facebook/facebook-php-sdk/src/Facebook/Helpers/FacebookRedirectLoginHelper.php
Строк: 513
<?php
/**
 * Copyright 2014 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 FacebookHelpers;

use 
FacebookAuthenticationAccessToken;
use 
FacebookAuthenticationOAuth2Client;
use 
FacebookUrlUrlDetectionInterface;
use 
FacebookUrlFacebookUrlDetectionHandler;
use 
FacebookUrlFacebookUrlManipulator;
use 
FacebookPersistentDataPersistentDataInterface;
use 
FacebookPersistentDataFacebookSessionPersistentDataHandler;
use 
FacebookPseudoRandomStringPseudoRandomStringGeneratorInterface;
use 
FacebookPseudoRandomStringMcryptPseudoRandomStringGenerator;
use 
FacebookPseudoRandomStringOpenSslPseudoRandomStringGenerator;
use 
FacebookPseudoRandomStringUrandomPseudoRandomStringGenerator;
use 
FacebookExceptionsFacebookSDKException;

/**
 * Class FacebookRedirectLoginHelper
 *
 * @package Facebook
 */
class FacebookRedirectLoginHelper
{
    
/**
     * @const int The length of CSRF string to validate the login link.
     */
    
const CSRF_LENGTH 32;

    
/**
     * @var OAuth2Client The OAuth 2.0 client service.
     */
    
protected $oAuth2Client;

    
/**
     * @var UrlDetectionInterface The URL detection handler.
     */
    
protected $urlDetectionHandler;

    
/**
     * @var PersistentDataInterface The persistent data handler.
     */
    
protected $persistentDataHandler;

    
/**
     * @var PseudoRandomStringGeneratorInterface The cryptographically secure pseudo-random string generator.
     */
    
protected $pseudoRandomStringGenerator;

    
/**
     * @param OAuth2Client                              $oAuth2Client          The OAuth 2.0 client service.
     * @param PersistentDataInterface|null              $persistentDataHandler The persistent data handler.
     * @param UrlDetectionInterface|null                $urlHandler            The URL detection handler.
     * @param PseudoRandomStringGeneratorInterface|null $prsg                  The cryptographically secure pseudo-random string generator.
     */
    
public function __construct(OAuth2Client $oAuth2ClientPersistentDataInterface $persistentDataHandler nullUrlDetectionInterface $urlHandler nullPseudoRandomStringGeneratorInterface $prsg null)
    {
        
$this->oAuth2Client $oAuth2Client;
        
$this->persistentDataHandler $persistentDataHandler ?: new FacebookSessionPersistentDataHandler();
        
$this->urlDetectionHandler $urlHandler ?: new FacebookUrlDetectionHandler();
        
$this->pseudoRandomStringGenerator $prsg ?: $this->detectPseudoRandomStringGenerator();
    }

    
/**
     * Returns the persistent data handler.
     *
     * @return PersistentDataInterface
     */
    
public function getPersistentDataHandler()
    {
        return 
$this->persistentDataHandler;
    }

    
/**
     * Returns the URL detection handler.
     *
     * @return UrlDetectionInterface
     */
    
public function getUrlDetectionHandler()
    {
        return 
$this->urlDetectionHandler;
    }

    
/**
     * Returns the cryptographically secure pseudo-random string generator.
     *
     * @return PseudoRandomStringGeneratorInterface
     */
    
public function getPseudoRandomStringGenerator()
    {
        return 
$this->pseudoRandomStringGenerator;
    }

    
/**
     * Detects which pseudo-random string generator to use.
     *
     * @return PseudoRandomStringGeneratorInterface
     *
     * @throws FacebookSDKException
     */
    
public function detectPseudoRandomStringGenerator()
    {
        
// Since openssl_random_pseudo_bytes() can sometimes return non-cryptographically
        // secure pseudo-random strings (in rare cases), we check for mcrypt_create_iv() first.
        
if (function_exists('mcrypt_create_iv')) {
            return new 
McryptPseudoRandomStringGenerator();
        }

        if (
function_exists('openssl_random_pseudo_bytes')) {
            return new 
OpenSslPseudoRandomStringGenerator();
        }

        if (!
ini_get('open_basedir') && is_readable('/dev/urandom')) {
            return new 
UrandomPseudoRandomStringGenerator();
        }

        throw new 
FacebookSDKException('Unable to detect a cryptographically secure pseudo-random string generator.');
    }

    
/**
     * Stores CSRF state and returns a URL to which the user should be sent to in order to continue the login process with Facebook.
     *
     * @param string $redirectUrl The URL Facebook should redirect users to after login.
     * @param array  $scope       List of permissions to request during login.
     * @param array  $params      An array of parameters to generate URL.
     * @param string $separator   The separator to use in http_build_query().
     *
     * @return string
     */
    
private function makeUrl($redirectUrl, array $scope, array $params = [], $separator '&')
    {
        
$state $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH);
        
$this->persistentDataHandler->set('state'$state);

        return 
$this->oAuth2Client->getAuthorizationUrl($redirectUrl$state$scope$params$separator);
    }

    
/**
     * Returns the URL to send the user in order to login to Facebook.
     *
     * @param string $redirectUrl The URL Facebook should redirect users to after login.
     * @param array  $scope       List of permissions to request during login.
     * @param string $separator   The separator to use in http_build_query().
     *
     * @return string
     */
    
public function getLoginUrl($redirectUrl, array $scope = [], $separator '&')
    {
        return 
$this->makeUrl($redirectUrl$scope, [], $separator);
    }

    
/**
     * Returns the URL to send the user in order to log out of Facebook.
     *
     * @param AccessToken|string $accessToken The access token that will be logged out.
     * @param string             $next        The url Facebook should redirect the user to after a successful logout.
     * @param string             $separator   The separator to use in http_build_query().
     *
     * @return string
     *
     * @throws FacebookSDKException
     */
    
public function getLogoutUrl($accessToken$next$separator '&')
    {
        if (!
$accessToken instanceof AccessToken) {
            
$accessToken = new AccessToken($accessToken);
        }

        if (
$accessToken->isAppAccessToken()) {
            throw new 
FacebookSDKException('Cannot generate a logout URL with an app access token.'722);
        }

        
$params = [
            
'next' => $next,
            
'access_token' => $accessToken->getValue(),
        ];

        return 
'https://www.facebook.com/logout.php?' http_build_query($paramsnull$separator);
    }

    
/**
     * Returns the URL to send the user in order to login to Facebook with permission(s) to be re-asked.
     *
     * @param string $redirectUrl The URL Facebook should redirect users to after login.
     * @param array  $scope       List of permissions to request during login.
     * @param string $separator   The separator to use in http_build_query().
     *
     * @return string
     */
    
public function getReRequestUrl($redirectUrl, array $scope = [], $separator '&')
    {
        
$params = ['auth_type' => 'rerequest'];

        return 
$this->makeUrl($redirectUrl$scope$params$separator);
    }

    
/**
     * Returns the URL to send the user in order to login to Facebook with user to be re-authenticated.
     *
     * @param string $redirectUrl The URL Facebook should redirect users to after login.
     * @param array  $scope       List of permissions to request during login.
     * @param string $separator   The separator to use in http_build_query().
     *
     * @return string
     */
    
public function getReAuthenticationUrl($redirectUrl, array $scope = [], $separator '&')
    {
        
$params = ['auth_type' => 'reauthenticate'];

        return 
$this->makeUrl($redirectUrl$scope$params$separator);
    }

    
/**
     * Takes a valid code from a login redirect, and returns an AccessToken entity.
     *
     * @param string|null $redirectUrl The redirect URL.
     *
     * @return AccessToken|null
     *
     * @throws FacebookSDKException
     */
    
public function getAccessToken($redirectUrl null)
    {
        if (!
$code $this->getCode()) {
            return 
null;
        }

        
$this->validateCsrf();

        
$redirectUrl $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl();
        
// At minimum we need to remove the state param
        
$redirectUrl FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['state']);

        return 
$this->oAuth2Client->getAccessTokenFromCode($code$redirectUrl);
    }

    
/**
     * Validate the request against a cross-site request forgery.
     *
     * @throws FacebookSDKException
     */
    
protected function validateCsrf()
    {
        
$state $this->getState();
        
$savedState $this->persistentDataHandler->get('state');

        if (!
$state || !$savedState) {
            throw new 
FacebookSDKException('Cross-site request forgery validation failed. Required param "state" missing.');
        }

        
$savedLen strlen($savedState);
        
$givenLen strlen($state);

        if (
$savedLen !== $givenLen) {
            throw new 
FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.');
        }

        
$result 0;
        for (
$i 0$i $savedLen$i++) {
            
$result |= ord($state[$i]) ^ ord($savedState[$i]);
        }

        if (
$result !== 0) {
            throw new 
FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.');
        }
    }

    
/**
     * Return the code.
     *
     * @return string|null
     */
    
protected function getCode()
    {
        return 
$this->getInput('code');
    }

    
/**
     * Return the state.
     *
     * @return string|null
     */
    
protected function getState()
    {
        return 
$this->getInput('state');
    }

    
/**
     * Return the error code.
     *
     * @return string|null
     */
    
public function getErrorCode()
    {
        return 
$this->getInput('error_code');
    }

    
/**
     * Returns the error.
     *
     * @return string|null
     */
    
public function getError()
    {
        return 
$this->getInput('error');
    }

    
/**
     * Returns the error reason.
     *
     * @return string|null
     */
    
public function getErrorReason()
    {
        return 
$this->getInput('error_reason');
    }

    
/**
     * Returns the error description.
     *
     * @return string|null
     */
    
public function getErrorDescription()
    {
        return 
$this->getInput('error_description');
    }

    
/**
     * Returns a value from a GET param.
     *
     * @param string $key
     *
     * @return string|null
     */
    
private function getInput($key)
    {
        return isset(
$_GET[$key]) ? $_GET[$key] : null;
    }
}
Онлайн: 1
Реклама