我有一个完全外部的Facebook iframe应用程序.我的意思是,一旦用户访问画布URL以加载应用程序,iframe应用程序中的所有链接都将转到我的服务器,并且画布页面永远不会刷新,除非用户导航到Facebook上的其他位置并返回(或浏览器刷新).
在Facebook创建iframe的应用程序的初始加载中,我传递了所有常用参数,如fb_sig_user,这允许我基于facebook用户创建内部应用程序会话.这个应用程序会话(不是 Facebook会话,它是我自己的应用程序会话)是我需要允许用户使用该应用程序.
问题出现一小时后.如果用户离开计算机,或使用该应用程序超过一个小时,Facebook会话将过期.有一些应用程序页面需要获取朋友信息,一旦FB会话过期,这些页面就会中断,抛出诸如"错误:会话密钥无效或不再有效"之类的错误.
我的问题是,是否有办法从iframe应用程序中刷新用户的Facebook会话,以防止它在一小时后过期.任何API调用都这样做吗?是否有Facebook Connect技巧可以ping通某些内容?有没有确定的方法让它保持活力?我找不到任何具体解决这个问题的例子.
胜利是我的!
有一个几乎完全无证的Facebook功能处理iframe会话,我在我的研究中发现了一个模糊的参考.然而,这个页面并没有真正解释它,只有在我的iframe中观看各种会话密钥几个小时后,我才能弄清楚发生了什么.
以前,我的iframe应用程序fb_whatever
在初始iframe加载发生时接收到通常的一轮参数.所以在我的应用程序中,我是按照每个请求执行此操作的:
if (isset($_REQUEST['fb_sig_session_key'])) {
$_SESSION['fb_sig_session_key'] = $_REQUEST['fb_sig_session_key'];
}
if (! empty($_SESSION['fb_sig_session_key'])) $this->facebook->api_client->session_key = $_SESSION['fb_sig_session_key'];
这段代码会fb_sig_session_key
在最初的应用程序加载时收到,我会把它放到本地$_SESSION
用于API.将它存储在本地会话中是必要的,因为fb_sig_session_key
除非重新加载整个应用程序iframe,否则永远不会再次传入.
因此,当此会话密钥在一个小时左右到期后发生问题.
在查看模糊的参考页面后,我开始检查$_REQUEST
我得到的所有变量.事实证明,即使在iframe应用程序内部的内部链接上,Facebook也会修改传递一些参数的请求.出于某种原因,他们有一个完全不同但也有效的会话密钥,它随每个iframe请求一起出现!
此参数以您的Facebook Application api密钥命名.因此,如果您的应用程序API密钥是"xyz123",则iframe中的每个请求都会获得一个名为的参数xyz123_session_key
(以及其他一些参数,如xyz123_expires
和xyz123_user
).
在观察主会话(原始fb_sig_session_key
)和此iframe唯一会话(xyz123_session_key
)的相关到期时间之后,隧道末端的灯出现: 仅iframe会话密钥到期时间实际上偶尔更新.我还没有确定何时或如何(我认为它在某些时候是一个Ajax ping),但仍然会刷新.
我等待原始fb_sig_session_key
会话过期,果然我的应用中的朋友相关页面开始咳嗽错误.此时,我将本地存储的会话密钥切换到新的iframe xyz123_session_key
,问题就解决了.该会议与原始会议一样有效!
所以,我最后的代码修复是在本地存储会话密钥,如下所示:
$iframeSessionKeyName = $CONFIG['facebook']['apiKey'] . '_session_key';
if (isset($_REQUEST[$iframeSessionKeyName])) {
$_SESSION['fb_sig_session_key'] = $_REQUEST[$iframeSessionKeyName];
}
else if (isset($_REQUEST['fb_sig_session_key'])) {
$_SESSION['fb_sig_session_key'] = $_REQUEST['fb_sig_session_key'];
}
if (! empty($_SESSION['fb_sig_session_key'])) $this->facebook->api_client->session_key = $_SESSION['fb_sig_session_key'];
这优先考虑"仅iframe"键.
编辑:我最初假设"iframe-only"键是通过某种Ajax方法更新的,这是错误的,事实证明这些值被Facebook设置为cookie.这在使用这些cookie时会导致一些跨域问题.设置P3P cookie策略将缓解除大多数浏览器之外的其他浏览器.Safari仍然没有好的工作.