Facebook PHP SDK 5 :: API 2.4 :: Cross-site reques

2019-01-22 21:26发布

I did a very simple PHP script, just to try to login via Facebook and get an accessToken. But when I try the following code, I get an Exception from the SDK : « Cross-site request forgery validation failed. Required param "state" missing. ».

Here is my code :

require_once __DIR__ . '/facebook-sdk-v5/autoload.php';
session_start();

$fb = new Facebook\Facebook([
    'app_id' => '{my-own-app-id}',
    'app_secret' => '{my-own-app-secret}'
]);

// Check to see if we already have an accessToken ?
if (isset($_SESSION['facebook_access_token'] )) {
    $accessToken = $_SESSION['facebook_access_token'];
    echo "Horray we have our accessToken:$accessToken<br />\n";

} else {
    // We don't have the accessToken
    // But are we in the process of getting it ? 
    if (isset($_REQUEST['code'])) {
        $helper = $fb->getRedirectLoginHelper();
        try {
            $accessToken = $helper->getAccessToken();
            } catch(Facebook\Exceptions\FacebookResponseException $e) {
              // When Graph returns an error
              echo 'Graph returned an error: ' . $e->getMessage();
              exit;
        } catch(Facebook\Exceptions\FacebookSDKException $e) {
              // When validation fails or other local issues
              echo 'Facebook SDK returned an error: ' . $e->getMessage();
            exit;
        }

        if (isset($accessToken)) {
              // Logged in!
              $_SESSION['facebook_access_token'] = (string) $accessToken;

              // Now you can redirect to another page and use the
              // access token from $_SESSION['facebook_access_token']

              echo "Finally logged in! Token:$accessToken";
        }           
    } else {
        // Well looks like we are a fresh dude, login to Facebook!
        $helper = $fb->getRedirectLoginHelper();
        $permissions = ['email', 'user_likes']; // optional
        $loginUrl = $helper->getLoginUrl('http://mywebsite.com/myapp/index.php', $permissions);

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

}

exit;

22条回答
相关推荐>>
2楼-- · 2019-01-22 22:08

For me this was happening due to 'persistent_data_handler' . By adding this in Facebook config, I was able to make it work.

session_start();
$fb = new Facebook\Facebook([
  'app_id'     => '6XXXXXXXXX',
  'app_secret' => '5XXXXXXXXXXXXXX',
  'default_graph_version' => 'v2.6', 
  'persistent_data_handler' => 'session'
  ]);
查看更多
倾城 Initia
3楼-- · 2019-01-22 22:12

you receive this error if you origin hostname is different than the target hostname once authenticated.

$loginUrl = $helper->getLoginUrl('http://mywebsite.com/myapp/index.php', $permissions);

with this statement, if the visitor on your website used http://www.mywebsite.com/ the cross-site error will be raised.

You must ensure that origin and target hostname are exactly the same, including the eventual www prefix.

Fixed version:

$loginUrl = $helper->getLoginUrl('http://'.$_SERVER['SERVER_NAME'].'/myapp/index.php', $permissions);
查看更多
迷人小祖宗
4楼-- · 2019-01-22 22:12

Finally, looking into FB code, I discovered that the problem "Cross-site request forgery validation failed. Required param “state” missing" and similars are caused by PHP variable $_SESSION['FBRLH_state'] that for some "strange" reason when FB call the login-callback file.

To solve it I store this variable "FBRLH_state" AFTER the call of function $helper->getLoginUrl(...). Is very important to do only after the call of this function due to is inside this function when the variable $_SESSION['FBRLH_state'] is populated.

Below an example of my code in the login.php:

$uri=$helper->getLoginUrl($uri, $permissions);
foreach ($_SESSION as $k=>$v) {                    
    if(strpos($k, "FBRLH_")!==FALSE) {
        if(!setcookie($k, $v)) {
            //what??
        } else {
            $_COOKIE[$k]=$v;
        }
    }
}
var_dump($_COOKIE);

And in the login-callback.php before calling all FB code:

foreach ($_COOKIE as $k=>$v) {
    if(strpos($k, "FBRLH_")!==FALSE) {
        $_SESSION[$k]=$v;
    }
}

Last, but not least, remember also to include code for PHP session so..

if(!session_id()) {
    session_start();
}
...
...
...
...
<?php session_write_close() ?>

I hope this response can help you to save 8-10 hours of work :) Bye, Alex.

查看更多
虎瘦雄心在
5楼-- · 2019-01-22 22:13

I had to add this lines in some servers:

$helper = $fb->getRedirectLoginHelper();
if (isset($_GET['state'])) {
    $helper->getPersistentDataHandler()->set('state', $_GET['state']);
}

I get this error randomly, depending of the server config.

查看更多
Lonely孤独者°
6楼-- · 2019-01-22 22:13

This is a common issue that many people facing in FB Api. this is only a SESSION problem. To solve this issue add some code like.

On callback script usually fb-callback.php add "session_start();" just before you include the facebook autoload file. and then "$_SESSION['FBRLH_state']=$_GET['state'];" after the "$helper = $fb->getRedirectLoginHelper();" line.

Example :

<?php 
session_start(); /*Add session start*/
include 'vendor/autoload.php';
include 'config.php'; /*Facebook Config*/
$helper = $fb->getRedirectLoginHelper();
$_SESSION['FBRLH_state']=$_GET['state']; /*Add This*/
try {
  $accessToken = $helper->getAccessToken();
} ?>
查看更多
Juvenile、少年°
7楼-- · 2019-01-22 22:14

session_start() at the beginning of both the scripts. I got solution from here: https://github.com/facebook/facebook-php-sdk-v4/issues/473

查看更多
登录 后发表回答