我有一个完全外部的Facebook iframe应用程序。我的意思是,一旦用户访问画布URL以加载应用程序,iframe应用程序中的所有链接都将转到我的服务器,并且画布页面永远不会刷新,除非用户导航到Facebook上的其他位置并返回(或浏览器刷新。)
在Facebook创建iframe的应用程序的初始加载中,我传递了所有常用参数,如fb_sig_user,这允许我基于facebook用户创建内部应用程序会话。这个应用程序会话(不是 Facebook会话,它是我自己的应用程序会话)是我需要允许用户使用该应用程序。
问题出现一小时后。如果用户离开计算机,或使用该应用程序超过一个小时,Facebook会话将过期。有一些应用程序页面需要获取朋友信息,一旦FB会话过期,这些页面就会中断,抛出错误,例如“错误:会话密钥无效或不再有效”。
我的问题是,是否有办法从iframe应用程序中刷新用户的Facebook会话,以防止它在一小时后过期。任何API调用都这样做吗?是否有Facebook Connect技巧可以ping通某些内容?有没有确定的方法让它保持活力?我找不到任何具体解决这个问题的例子。
答案 0 :(得分:21)
胜利是我的!
有一个几乎完全无证的Facebook功能处理iframe会话,我在研究中发现vague reference to。然而,这个页面并没有真正解释它,只有在我的iframe中观看各种会话密钥几个小时之后,我才能弄清楚发生了什么。
以前,当初始iframe加载发生时,我的iframe应用程序正在接收通常的fb_whatever
参数轮。所以在我的应用程序中,我是按照每个请求执行此操作的:
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。
所以当这个会话密钥在一个小时后到期时会出现问题。
在查看vague reference page后,我开始检查我得到的所有$_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-only会话密钥到期时间实际上偶尔会更新。我还没有确定何时或如何(我认为它在某些时候是一个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-only”键。
编辑:我最初假设“iframe-only”键是通过某种Ajax方法更新的,这是错误的,事实证明这些值被Facebook设置为cookie。这在使用这些cookie时会导致一些跨域问题。设置P3P cookie policy可以缓解大多数浏览器,除了Safari。 Safari仍然没有好的工作。
答案 1 :(得分:2)
刚刚放
header('P3P: CP="CAO PSA OUR"');
位于页面顶部,您不会在iframe中丢失会话。
我也注意到这个帖子好了2年半。我偶然发现了使用谷歌。也许我的帖子会帮助遇到此事的其他人。