Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
496 views
in Technique[技术] by (71.8m points)

php - Facebook SDK returned an error: Cross-site request forgery validation failed. The "state" param from the URL and session do not match

i'm trying to get Facebook user id using the php sdk like this

$fb = new FacebookFacebook([
    'app_id' => '11111111111',
    'app_secret' => '1111222211111112222',
    'default_graph_version' => 'v2.4',
]);

$helper = $fb->getRedirectLoginHelper();


$permissions = ['public_profile','email']; // Optional permissions
$loginUrl = $helper->getLoginUrl('http://MyWebSite', $permissions);

echo '<a href="' . $loginUrl . '">Log in with Facebook!</a>';


    try {
        $accessToken = $helper->getAccessToken();
        var_dump($accessToken);
    } catch (FacebookExceptionsFacebookResponseException $e) {
        // When Graph returns an error
        echo 'Graph returned an error: ' . $e->getMessage();
        exit;
    } catch (FacebookExceptionsFacebookSDKException $e) {
        // When validation fails or other local issues
        echo 'Facebook SDK returned an error: ' . $e->getMessage();
        exit;
    }

    if (!isset($accessToken)) {
        if ($helper->getError()) {
            header('HTTP/1.0 401 Unauthorized');
            echo "Error: " . $helper->getError() . "
";
            echo "Error Code: " . $helper->getErrorCode() . "
";
            echo "Error Reason: " . $helper->getErrorReason() . "
";
            echo "Error Description: " . $helper->getErrorDescription() . "
";
        } else {
            header('HTTP/1.0 400 Bad Request');
            echo 'Bad request';
        }
        exit;
    }

// Logged in
    echo '<h3>Access Token</h3>';
    var_dump($accessToken->getValue());

// The OAuth 2.0 client handler helps us manage access tokens
    $oAuth2Client = $fb->getOAuth2Client();

// Get the access token metadata from /debug_token
    $tokenMetadata = $oAuth2Client->debugToken($accessToken);
    echo '<h3>Metadata</h3>';
    var_dump($tokenMetadata);

// Validation (these will throw FacebookSDKException's when they fail)
    $tokenMetadata->validateAppId($config['11111111111']);
// If you know the user ID this access token belongs to, you can validate it here
//$tokenMetadata->validateUserId('123');
    $tokenMetadata->validateExpiration();

    if (!$accessToken->isLongLived()) {
        // Exchanges a short-lived access token for a long-lived one
        try {
            $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
        } catch (FacebookExceptionsFacebookSDKException $e) {
            echo "<p>Error getting long-lived access token: " . $helper->getMessage() . "</p>

";
            exit;
        }

        echo '<h3>Long-lived</h3>';
        var_dump($accessToken->getValue());
    }

    $_SESSION['fb_access_token'] = (string)$accessToken;

but it give me this error:

Facebook SDK returned an error: 
Cross-site request forgery validation failed. 
The "state" param from the URL and session do not match.

please any help i'm new in php and Facebook sdk's thank for any help in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I found that as long as I enabled PHP sessions before generating the login url, and at the top of the script Facebook eventually redirects to, it works just fine on its own without setting a cookie (as per ale500's answer). This is using the 5.1 version of the sdk.

At the top of both scripts, I added...

if(!session_id()) {
    session_start();
}

...and it "just worked".

Here's a barebones complete example that worked for me:

auth.php

if (!session_id()) {
    session_start();
}

$oFB = new FacebookFacebook([
    'app_id'     => FACEBOOK_APP_ID,
    'app_secret' => FACEBOOK_APP_SECRET
]);

$oHelper = self::$oFB->getRedirectLoginHelper();
$sURL = $oHelper->getLoginUrl(FACEBOOK_AUTH_CALLBACK, FACEBOOK_PERMISSIONS);

// Redirect or show link to user.

auth_callback.php

if (!session_id()) {
    session_start();
}

$oFB = new FacebookFacebook([
    'app_id'     => FACEBOOK_APP_ID,
    'app_secret' => FACEBOOK_APP_SECRET
]);

$oHelper = self::$oFB->getRedirectLoginHelper();
$oAccessToken = $oHelper->getAccessToken();
if ($oAccessToken !== null) {
    $oResponse = self::$oFB->get('/me?fields=id,name,email', $oAccessToken);
    print_r($oResponse->getGraphUser());
}

Why?

As an additional note, this is explained in the Docs on the repo. Look at the warning on this page.

Warning: The FacebookRedirectLoginHelper makes use of sessions to store a CSRF value. You need to make sure you have sessions enabled before invoking the getLoginUrl() method. This is usually done automatically in most web frameworks, but if you're not using a web framework you can add session_start(); to the top of your login.php & login-callback.php scripts. You can overwrite the default session handling - see extensibility points below.

I'm adding this note because it's important to keep in mind should you happen to be running your own session management or if you're running multiple web servers in parallel. In those cases, relying upon php's default session methods won't always work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...