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:03

If you're using a "www" version of your site to generate the login link and you get redirected to the non-www version, you'll run into issues with your session. So make sure you access the www version of your site and then define the callback url to the same www version. Also, you can define permanent redirects in your server configuration to make sure anyone accessing your site from the non-www version gets redirected to the www version or vice versa.

查看更多
We Are One
3楼-- · 2019-01-22 22:04

For me the solution was catching the exception by replacing the namespaced Facebook\Exceptions\FacebookSDKException to just Exception, because the script already used it.

use Facebook\Facebook;

// code ...

$fb = new Facebook([
    'app_id' => FB_APP_ID,
    'app_secret' => FB_APP_SECRET,
    'default_graph_version' => 'v2.5',
]);

$helper = $fb->getRedirectLoginHelper();
try {
    $accessToken = $helper->getAccessToken();
} catch (Exception $e) {
    echo $e->getMessage();
    exit;
}
查看更多
Fickle 薄情
4楼-- · 2019-01-22 22:05

Finally after all this nice errors , i fixed all my problems with another solution , the example from facebook developer docs are outdated .

SDK V5 and APi 2.4 works like in this tutorial described , the access token need to be defined

Be sure you fill APP-IP|APP-SECRET with your credentials .

Example from tutorial :

$fb = new Facebook\Facebook([
      'app_id' => 'APP-ID',
      'app_secret' => 'APP-SECRET',
      'default_graph_version' => 'v2.4',
      'default_access_token' => 'APP-ID|APP-SECRET'
]);

Use this and not the example on developer facebook docs .

Have fun :)

查看更多
戒情不戒烟
5楼-- · 2019-01-22 22:06

Setting [PersistentDataHandler] explicitly before you get your tokens will guarantee that the request will be a success. Below shows how to fetch $_GET['state'] & simply inject it into the "to be used [helper]" on Symfony 2.x | 3.x

I had the exact same issue as the O.P. and this fixed my problem.

//create your new facebook sdk instance
$this->fb = new Facebook([
   'app_id' => $facebookAppId,
   'app_secret' =>$facebookAppSecret,
   'default_graph_version' =>$facebookDefaultGraphVersion
]);    

//retrieve the helper
$this->helper = $this->fb->getRedirectLoginHelper();

//below is the money shot
//setting this explicitly before you get your tokens will guarantee that the request will be a success. It Fetches $_GET['state'] & simply injects it into the "to be used [helper]"
$this->helper->getPersistentDataHandler()->set('state', $request->query->get('state'));
查看更多
Deceive 欺骗
6楼-- · 2019-01-22 22:06

I ran into similar problem and found Nanang Koesharwanto's solution. It's more like quirk as modifying source files in vendor directory is a very bad idea. So here's the trick.

public function callback(Request $request)
{
    $this->helper->getPersistentDataHandler()->set('state', $request->state);
    return $this->helper->getAccessToken();
}

If it fails put use Session; in your controller.

查看更多
7楼-- · 2019-01-22 22:07

If the session_start() does not still solve the problem, you put a wrong URI in the Valid OAuth Redirect URI of your Facebook developer app.

To solve: First, go to your fb-callback.php, find the URI you put in the header function, example: header("Location: https://localhost/home.php"). Then go to your Facebook developer apps and then in the sidebar, click Facebook Login which is under the Products tab then click Settings. In the Valid OAuth Redirect URIs, add the URI you put in the header. From my example, I will put https://localhost/home.php.

Hope this helps.

查看更多
登录 后发表回答