在 PHP 3.0 SDK 中,没有getSession()或没有任何来自 Facebook api 外部的会话处理可用。根据此博客条目和此错误报告,几天前 facebook 的开发人员也以某种方式更新了 JavaScript sdk 。
在最近几天内,托管 JS SDK 中引入了一项更改,这破坏了它与当前 PHP SDK(2.x 和 3.x)之间的所有兼容性。在其网站上同时使用 JS 和 PHP SDK 的开发人员很可能会看到服务器端 API 失败。
但是,我不知道这是否真的影响了我的问题。就像在这个问题的答案中一样,我正在使用 PHP 检索 OAuth 对话框的访问令牌,并将新的访问令牌保存在会话中。
当前的解决方法
以下代码显示了我如何处理此会话。$_REQUEST['session']是 OAuth 对话框响应的内容。
if(isset($_REQUEST['session'])) {
$response = json_decode(stripslashes($_REQUEST['session']), true);
if(isset($response['access_token'])) {
$this->api->setAccessToken($response['access_token']);
$_SESSION['access_token'] = $this->api->getAccessToken();
}
}
elseif(isset($_SESSION['access_token']) && ! isset($_REQUEST['signed_request']))
$this->api->setAccessToken($_SESSION['access_token']);
elseif(isset($_REQUEST['signed_request'])) {
Session::invalidate('fbuser');
$_SESSION['access_token'] = '';
}
这是我处理用户数据的方式:
try {
$this->user = Session::getVar('fbuser');
if ($this->user === false || is_null($this->user)) {
$facebookUser = $this->api->api('me?fields=id,name,first_name,last_name');
$this->user = new FBUserModel(array('fbId' => $facebookUser['fbId'], ...));
Session::setVar('fbuser', $this->user);
}
}
问题
测试时一切正常。仅发生一次错误:设置权限后的第一次。现在,由于该应用程序在线,似乎平均每第二个用户都会发生错误
$facebookUser = $this->api->api('me?fields=id,name,first_name,last_name');
有错误:
An active access token must be used to query information about the current user.
问题
那么为什么会发生这种情况呢?调试非常困难,因为错误似乎只发生在用户第一次进入应用程序时,在应用程序身份验证和访问令牌更改后。甚至这也不是每次都发生。我应该如何使用新的 PHP SDK 正确处理会话和访问令牌?
任何帮助将不胜感激!
编辑
我发现 iFrame 中的 cookie/会话存在一些 IE 问题。正如这篇博文中所见。有了这个提示和一些进一步的研究,我在引导程序中添加了以下几行:
ini_set('session.use_trans_sid', 1);
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
现在好多了,但是大约 50 个用户中有 2 个的信息在登陆页面(身份验证)-> 公式-> 和注册之间丢失了。所以我仍然遗漏了一些东西。
编辑 2
我编辑了我的用户处理
if ($this->user === false || is_null($this->user)) {
// get user data
}
到
if ((is_object($this->user) && $this->user->fbId == '') || $this->user === false || is_null($this->user)) {
// get user data
}
这似乎有点帮助。我认为主要问题出在我的会话中。
此外,我添加了一个 try/catch 块来查看我的应用程序中是否有 FacebookOAuthException被抛出。如果是这种情况,我会将顶部位置重定向到 Facebook Page 和 Tab 以获取新的签名请求。虽然这可能有助于解决这个问题,但我想防止我的应用程序必须重定向用户。
编辑 3
经过几天的密集调试和日志记录,我发现$_REQUEST['session']来自FB.ui permissions.request 方法的消息很少为空。
这是我的处理方式:
这是我一直包括的东西:
FB.provide("UIServer.Methods", {'permissions.request': {size : {width: 575, height: 300}, url: 'connect/uiserver.php', transform : FB.UIServer.genericTransform}});
这个函数在表单提交时调用。一直为我工作,但不知何故它仍然发送表单,尽管session == ''.
function getPermission(form) {
session = $('#' + $(form).attr('id') + ' input[name="session"]');
if($(session).val() != '') {
form.submit();
return;
}
FB.ui({method: "permissions.request", "perms": 'user_photos'}, function callback(info){
if(info.status=='connected' && info.session !== null) {
$(session).val(JSON.stringify(info.session));
form.submit();
}
});
return;
}