EDIT: This bug was logged, and confirmed as a Facebook bug. It has now been fixed!
I am testing my updates to move onto the new JS SDK. My app runs across multiple subdomains of my domain. On the old JDK, I was calling something like this:
FB.init({
appId: [APP_ID],
status: false,
cookie: true,
xfbml: true
});
FB.login();
On the new JDK, it looks like this:
FB.init({
appId: [APP_ID],
status: false,
cookie: true,
xfbml: true,
oauth:true
});
FB.login();
Using a cookie manager FF add on, you can see that the old version would set a cookie on mydomain.com, but the new one sets it to www.mydomain.com - meaning my other subdomain cannot access the cookie.
To clarify: The problem is that I cannot use the facebook cookie on different subdomains, and also if I log them in on every subdomain, I have to log them out from every subdomain too
If you set oauth to true when calling FB.init() via the Javascript API, you now get an fbsr_APP_ID cookie instead of a fbs_APP_ID cookie (notice the "r"). It contains a signed request and part of the oauth migration.
If you use the PHP SDK, it should take care of the change.
However, the docs for websites do not appear to be updated with a new get_facebook_cookie() function: https://developers.facebook.com/docs/guides/web/
It still uses the old cookie format. You can find how to parse a signed request here:
http://developers.facebook.com/docs/authentication/signed_request/
Then, you need to turn the "code" parameter in the cookie into an access_token via the docs here: developers.facebook.com/docs/authentication/ (no http:// because of StackOverflow spam prevention)
I dug around in the source of the new PHP SDK a little bit to figure this out since all of the documentation does not appear to be updated.
The full code that I am using is a combination of the above with a little extra modifications to work with the old or new cookie format is below. The new get_facebook_cookie() function does return a few additional array elements (algorithm, code, issued_at, user_id) and a few array elements are no longer set (base_domain, secret, session_key, sig). The primary parameters most people are looking for are most likely set though (uid, access_token, and expires)
function get_facebook_cookie($app_id, $app_secret) {
if ($_COOKIE['fbsr_' . $app_id] != '') {
return get_new_facebook_cookie($app_id, $app_secret);
} else {
return get_old_facebook_cookie($app_id, $app_secret);
}
}
function get_old_facebook_cookie($app_id, $app_secret) {
$args = array();
parse_str(trim($_COOKIE['fbs_' . $app_id], '\\"'), $args);
ksort($args);
$payload = '';
foreach ($args as $key => $value) {
if ($key != 'sig') {
$payload .= $key . '=' . $value;
}
}
if (md5($payload . $app_secret) != $args['sig']) {
return array();
}
return $args;
}
function get_new_facebook_cookie($app_id, $app_secret) {
$signed_request = parse_signed_request($_COOKIE['fbsr_' . $app_id], $app_secret);
// $signed_request should now have most of the old elements
$signed_request[uid] = $signed_request[user_id]; // for compatibility
if (!is_null($signed_request)) {
// the cookie is valid/signed correctly
// lets change "code" into an "access_token"
$access_token_response = file_get_contents("https://graph.facebook.com/oauth/access_token?client_id=$app_id&redirect_uri=&client_secret=$app_secret&code=$signed_request[code]");
parse_str($access_token_response);
$signed_request[access_token] = $access_token;
$signed_request[expires] = time() + $expires;
}
return $signed_request;
}
Update: The bug has been updated by Facebook to 'Fixed'. Hooray!
This is a facebook bug and has been logged, reproduced and accepted as high priority here: https://developers.facebook.com/bugs/256155664428653?browse=search_4e843e6d89a232275456793
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With