Recently, I ran into the same problem, it seems that if after 5 minutes or so inactivity you are rebooting, the session is not saved. Sometimes it works, sometimes it doesnโt.
I studied it about last week, and the only solution I could think of was to use the JS SDK to reload the page:
FB.Event.subscribe('auth.login', function(response) { window.location.reload(); });
But I agree, this is not a very elegant solution in terms of UX. You should pass the cookie parameter in the PHP SDK and the oauth parameter in the JS SDK and see if this works (this is not for me):
$facebook = new Facebook(array( 'appId' => $config['facebook']['id'], 'secret' => $config['facebook']['secret'], 'cookie' => true ));
AND
FB.init({ appId : appId, channelUrl : '//domain.com/signon/channel.php', status : true, cookie : true, xfbml : true, oauth : true });
Oddly enough, I reloaded the latest PHP SDK from Github and loaded it into the sandbox environment (Apache, PHP 5.4). I ran the AS-IS example (with the JS SDK) and it has the same problem!
Now, if the above just doesn't cut the mustard, I have a few more suggestions.
CHANGE SDK UP A BIT
First walkthrough
$facebook->getAccessToken();
it won't do you any good if $user returns 0. However, after a little search in base_facebook.php , I noticed that the getCode() method actually uses $_REQUEST to extract the authorization code from the request parameters.
from the PHP manual, $ _REQUEST -
An associative array that by default contains the contents of $ _GET, $ _POST and $ _COOKIE.
BUT
This is very different from $ _GET, $ _ POST or $ _COOKIE.
Depending on your setup, this may be a bit of a glucometer. Instead, find the getCode() function in base_facebook.php , which looks like this:
protected function getCode() { if (isset($_REQUEST['code'])) { if ($this->state !== null && isset($_REQUEST['state']) && $this->state === $_REQUEST['state']) { // CSRF state has done its job, so clear it $this->state = null; $this->clearPersistentData('state'); return $_REQUEST['code']; } else { self::errorLog('CSRF state token does not match one provided.'); return false; } } return false; }
and combine the request into a new array / variable (let it call it $code_array ) to include the $_GET , $_POST and $_COOKIE using array_merge() :
$code_array = array_merge($_GET,$_POST,$_COOKIE);
As a result, you get an array containing all the data from the corresponding queries. Just go back and replace $_REQUEST with $code_array inside the function, i.e.
\\replace $_REQUEST with $code_array; if (isset($code_array['code'])) { if ($this->state !== null && isset($code_array['state']) && $this->state === $code_array['state']) {
This should do the job nicely (hopefully).
OPTIONAL - Extension of the access token
This is optional, but I turned it on anyway. Most new applications have been using access tokens for a long time, but just in case, you can use the $facebook->setExtendedAccessToken(); method $facebook->setExtendedAccessToken(); to convert an existing access token.
Note. . You must call $facebook->setExtendedAccessToken(); before you get your access token using the getAccessToken() method.
Now, using your code, you will have
$user = $facebook->getUser(); if($user) { try { // Just to be sure, add access token to each request $facebook->setExtendedAccessToken(); $access_token = $facebook->getAccessToken(); // Fetch user details $user = $facebook->api('/me?access_token='.$access_token); } //and so on..
Conclusion
Breaking $ _REQUEST into $ _GET, $ _ POST and $ _COOKIE (Despite the fact that it includes all three by default), it looks like we can get a cookie that was installed by SDK (s) without any problems. I say it seems because the hell, I'm not really 100% sure.
I used the above methods to make it work in my case, so I hope to share some knowledge, since I am losing this problem too much and cannot find a viable solution.
Hope this helps!
EDIT: I forgot to mention changing the API request from
$user_profile = $facebook->api('/me');
to
$user_profile = $facebook->api('/'.$user.'?access_token='.$access_token);
was what I did too, and that mattered. :)