带有OAuth 2.0的新JS SDK将子域保存在fbsr_cookie中

New JS SDK with OAuth 2.0 saving subdomain in fbsr_ cookie?

本文关键字:存在 保存 fbsr cookie OAuth 的新 SDK JS 带有      更新时间:2023-09-26

EDIT:此错误已被记录,并被确认为Facebook错误。现在已经修复!



我正在测试我的更新,以便使用新的JS SDK。我的应用程序在我的域的多个子域中运行。在旧JDK上,我称之为:

FB.init({
    appId: [APP_ID],
    status: false,
    cookie: true,
    xfbml: true
});
FB.login();

在新的JDK上,它看起来是这样的:

FB.init({
    appId: [APP_ID],
    status: false,
    cookie: true,
    xfbml: true,
    oauth:true
});
FB.login();

使用cookie管理器FF插件,你可以看到旧版本会在mydomain.com上设置cookie,但新版本会将其设置为www.mydomain.com,这意味着我的其他子域无法访问cookie。

澄清一下:问题是我不能在不同的子域上使用facebook cookie,而且如果我在每个子域上登录他们,我也必须从每个子域中注销他们。

如果在通过Javascript API调用FB.init((时将oauth设置为true,则现在将获得fbsr_APP_ID cookie,而不是fbs_APP_ID cookie(请注意"r"(。它包含一个已签名的请求和oauth迁移的一部分。

如果您使用PHP SDK,它应该负责更改。

但是,网站的文档似乎没有使用新的get_facebook_cookie((函数进行更新:https://developers.facebook.com/docs/guides/web/

它仍然使用旧的cookie格式。您可以在这里找到如何解析签名请求:

http://developers.facebook.com/docs/authentication/signed_request/

然后,您需要通过此处的文档将cookie中的"code"参数转换为access_token:developers.facebook.com/docs/authentication/(由于StackOverflow防止垃圾邮件,因此没有http://(

由于所有的文档似乎都没有更新,我在新的PHP SDK的源代码中挖掘了一点来弄清楚这一点。

我正在使用的完整代码是上面的组合,并进行了一些额外的修改,以使用旧的或新的cookie格式。新的get_facebook_cookie((函数确实返回了一些额外的数组元素(algorithm、code、issued_at、user_id(,并且不再设置一些数组元素(base_domain、secret、session_key、sig(。大多数人正在寻找的主要参数很可能是设置的(uid、access_token和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;
}

更新:Facebook已将该错误更新为"已修复"。好极了

这是一个facebook错误,已被记录、复制并在此处被视为高度优先事项:https://developers.facebook.com/bugs/256155664428653?browse=search_4e843e6d89a232275456793

1(检查您的应用程序。设置中的域设置为mydomain.com,而不是www.mydomain.com
2( 在init:中使用通道文件和url

FB.init({  
appId : [APP_ID],  
status : false,  
cookie : true,  
xfbml : true,
channelUrl : document.location.protocol + "//domain.com/xd_receiver.html",  
oauth : true
});  

https://developers.facebook.com/docs/reference/javascript/FB.init/

希望这对有帮助

看看这个https://developers.facebook.com/apps/<appid>/摘要

查看应用程序域:"基本信息:"的一部分
如果指定"www.example.com",则它仅适用于www.example.com。如果使用"example.com"则它将视为*.example.com并适用于所有子域