在Facebook创建iframe的应用程序的初始加载中,我通过了所有通常的参数,如fb_sig_user,它允许我基于Facebook用户创建一个内部应用程序会话.这个应用程序会话(这不是Facebook会话,这是我自己的应用程序会话)是我需要允许用户使用该应用程序.
问题一小时后出现.如果用户离开计算机,或者使用该应用超过一个小时,则Facebook会话过期.有一些应用程序页面需要获取朋友信息,一旦FB会话已过期,这些页面会中断,从而抛出错误,例如“错误:会话密钥无效或不再有效”.
我的问题是,是否有办法从iframe应用程序中刷新用户的Facebook会话,以防止一个小时之后到期.任何API调用都会这样做吗?有没有一个Facebook Connect的伎俩来平ping?有没有确定的方法来保持活着?我没有找到任何具体解决这个问题的例子.
解决方法
有几乎完全没有文档的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应用程序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”键.
编辑:我原来假设“iframe-only”键通过某种Ajax方法更新是错误的,事实证明这些值被Facebook设置为一个cookie.这会导致使用这些Cookie时的一些跨域问题.大多数浏览器设置一个P3P cookie policy可以缓解这一点,Safari除外. Safari还没有很好的工作.