5

所以我试图用与Facebook的JS SDK中的图形API和我得到的Safari以下错误:使用Facebook图形API被打破

“OAuthException:必须使用活动的访问令牌来查询有关当前用户的信息。”

我怀疑它与Safari对x域cookie设置非常严格的事实有关,所以我在Firefox中试过它,cookie选项在FB.init()中设置为false。我的确发现我的FB.api()请求中出现同样的错误。

FB.init({ 
    appId: "<%= app_id %>", 
    status: true, // check login status 
    // We cannot rely on this cookie being set in an iframe. I found this 
    // out because the Graph API was not working in Safari. 
    // cookie: true, // enable cookies to allow the server to access the session 
    xfbml: true, // parse XFBML 
    channelUrl: window.location.protocol + '//' + window.location.host + '/fb/canvas/channel.html' 
}); 

所以我不知道...有手动设置在FB.api()请求access_token查询参数的好办法?

如果FB.init() Cookie会设置正确,这个是什么FB.api()请求参数如下所示:

access_token xxxxxxxxxxxx|1.xxxxxxxxxxxxxxxxxxxxxx__.3600.xxxxxxxxxx-xxx|xxxxxxxxxxxxxxxxxxxxxxxxxxx 
callback  FB.ApiServer._callbacks.xxxxxxxxxxxxxxx 
pretty  0 
sdk   joey 

在Safari浏览器(或当cookieFB.init()选项未设置)的FB.api()请求参数如下所示:

callback  FB.ApiServer._callbacks.xxxxxxxxxxxxxxx 
pretty  0 
sdk   joey 

现在...显然我的应用程序有能力在服务器端生成access_token ...我想知道是否有任何方法我可以手动设置FB.api()使用我的服务器端生成的access_token

+0

我想有另一种方法来做到这一点。基本上,由于我们有一次机会在填充iFrame的初始post请求中设置cookie,所以我们可以使用这个机会来模拟FB JS中在FB.init()期间尝试设置的`fbs_xxxxxxxxx` cookie。现在... SDK设置的cookie值如下所示:`fbs_xxxxxxxxx =“access_token = xxx&expires = xxx&secret = xxx&session_key = xxx&sig = xxx&uid = xxx”`。 `access_token`和`expires`部分很容易。但我在计算其他部分时遇到了一些麻烦。 – 2011-02-01 17:01:19

回答

4

好,我得到它的工作找到一个很好的例子。我原来你不需要FB.init()cookie: true选项,以便使用FB.api() - 您可以手动传递的access_token:

FB.api("/me/apprequests/?access_token="+access_token, function (response) {}); 

哪里access_token是您在页面加载设置服务器端的一个JS变量。下面是一个ERB例如:

<script> 
    var access_token = "<%= @access_token %>"; 
</script> 

而且@access_token是获取传递给你的画布页在初始POST请求的OAuth的access_token。

3

Safari的限制是,如果域名与父域不同,它将不允许iframe的内容创建或使用cookie,除非用户首先与其交互。这个问题是Safari独有的,不是webkit,所以Chrome很好。

自己遇到这个问题后(几个痛苦的时刻),有一个解决方案似乎是一个很好的解决方法。该技术是使用JavaScript将表单注入页面主体,然后触发提交事件。 Safari将此视为用户交互并允许Cookie。

您可以在Facebook开发人员论坛here

+0

啊,不是一个坏主意。我知道JS触发表单提交是Facebook如何允许iFrame canvas页面为iFrame的域设置cookie,即使在像Safari这样的浏览器上,通常不会在x域iFrame请求上设置cookie(http://stackoverflow.com /问题/ 4701922 /如何,的确,Facebook的设置跨域饼干换I帧,画布上的页面)。但是,似乎从iFrame内部触发表单提交事件(或执行JS重新加载)并不是最好的用户体验。另外,Safari团队可能会将其视为一种安全漏洞,可以防范跟踪用户的广告。 – 2011-02-01 16:54:56