So I posted a previous question before about this, but deleted it because I've discovered my problem.
Basically, I was getting this error:
Facebook SDK returned an error: Cross-site request forgery validation failed. The "state" param from the URL and session do not match.
I was able to pinpoint that for some bizarre reason, my $_SESSION['FBRLH_state']
as changing. Here is the login.php
that generates the login url for the user:
session_start();
}
require_once $_SERVER['DOCUMENT_ROOT'] . '/src/Facebook/autoload.php';
$fb = new Facebook\Facebook ([
'app_id' => '??????',
'app_secret' => '????',
'default_graph_version' => 'v2.4'
]);
$helper = $fb->getRedirectLoginHelper();
$loginUrl = $helper->getLoginUrl('http://example.ca/login-callback.php');
echo '<a href="' . $loginUrl . '">Login</a>';
print_r($_SESSION);
When I do a print_r($_SESSION);
, I get this:
Array ( [FBRLH_state] => d116b427b433a0b3dc41a858782cd690 )
However (get ready for the magic), upon redirection to the login-callback.php
file, the array of $_SESSION
mysteriously changes to this:
Array ( [FBRLH_state] => e99c4ece0f8e48ab53dea6a4826c5593 )
Here is the code for login-callback.php
<?php
header("Content-type: text/html;charset=utf-8");
session_start();
print_r($_SESSION);
require_once $_SERVER['DOCUMENT_ROOT'] . '/src/Facebook/autoload.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/Database.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/User.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/vars/constants.php';
//Create the Facebook service
$fb = new Facebook\Facebook ([
'app_id' => '????',
'app_secret' => '????',
'default_graph_version' => 'v2.4'
]);
$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)) {
$mysqli = Database::connection();
// Logged in!
$_SESSION['facebook_access_token'] = (string) $accessToken;
When I print $_SESSION
(the first thing I do right after the headers
), I get a completely different value from the login.php
one. It makes no sense because they're both on the same domain (non-www) and they have the same document.cookie
PHPSESSID
But, there's a catch. If I press back on login-callback.php
(since login.php
redirects to it, and then the login fails due to this weird session magic), the $_SESSION
values mysteriously match. This doesn't work if I refresh, ONLY when I press back. I think this is some important clue as to what's going on but I have no idea.
Can someone please help me on this extremely frustrating issue? Anyone with any idea of what might be going on?
Edit: Also, I created a blank file with just
session_start();
print_r($_SESSION);
And the values I get always match login-callback.php
which means that login.php
must be changing some session values (but.... I can't figure out how since when I print_r($_SESSION);
at the bottom of the file I still get the same weird values)