繁体   English   中英

Facebook PHP SDK会话丢失,需要JS SDK刷新

[英]Facebook PHP SDK session lost, needs JS SDK refresh

真的很奇怪,使用PHP SDK(v 3.2.2)似乎丢失了Facebook会话($ user = 0)。 JS SDK需要重新加载我的页面以恢复Facebook会话。 这个问题偶尔会发生,有时Facebook会话会丢失,有时它会正常工作。

session_start();

// Run Facebook API
$facebook = new Facebook(array(
  'appId'  => $config['facebook']['id'],
  'secret' => $config['facebook']['secret']
));

// Fetch user
$user = $facebook->getUser();
if($user) {
  try {
    // Just to be sure, add access token to each request
    $user['access_token'] = $facebook->getAccessToken();    

    // Fetch user details
    $user = $facebook->api('/me?access_token='.$user['access_token']);          
  }
  catch (FacebookApiException $e) {
    error_log($e);
    $user = null;
  } 
}

主要问题是$ user = $ facebook-> getUser(); 但是,当用户实际连接时,JS SDK会检测auth.login事件并重新加载页面(另一个奇怪的事情是,我使用auth.login,因为auth.authResponseChange事件每秒都会被触发)。 现在$ user = $ facebook-> getUser(); 返回用户的uid。

window.fbAsyncInit = function() {
  FB.init({
    appId : appId,
    channelUrl : '//domain.com/signon/channel.php',
    status     : true,
    cookie     : true,
    xfbml      : true 
  });
  FB.Event.subscribe('auth.login', function(response) {
    location.reload();
  });
};

在Facebook Developer中,我定义了App Domain(domain.com)和Site Url( http://domain.com/ )。 已经尝试使用/不带斜杠的Site Url,没有解决问题。

知道发生了什么,为什么Facebook PHP SDK没有立即检测到用户的会话/不断丢失用户的会话并需要重新加载? 这个问题确实导致用户体验不好。

非常感谢!

知更鸟

我最近遇到了同样的问题,似乎如果你在5分钟左右的时间没有进行重新加载,那么会话就不会持续存在。 有时候它有效,有时则不然。

我在上周一直在研究它,我能想到的唯一解决方案是使用JS SDK进行页面重新加载:

FB.Event.subscribe('auth.login', function(response) {
      window.location.reload();
    });

但我同意,就UX而言,这不是一个非常优雅的解决方案。 您应该在PHP SDK中传递cookie参数,在JS SDK中传递oauth参数,看看它是否有效(它不适合我):

$facebook = new Facebook(array(
  'appId'  => $config['facebook']['id'],
  'secret' => $config['facebook']['secret'],
  'cookie' => true
));

FB.init({
    appId : appId,
    channelUrl : '//domain.com/signon/channel.php',
    status     : true,
    cookie     : true,
    xfbml      : true,
    oauth      : true
  }); 

甚至更奇怪的是,我从Github重新下载了最新的PHP SDK并将其上传到沙箱环境(Apache,PHP 5.4)。 我运行示例(使用JS SDK)AS-IS,它有同样的问题!

现在,如果以上只是没有削减芥末,我还有一些建议。

改变SDK的位置

首先,通过

$facebook->getAccessToken();

如果$user返回0,那对你没有$user但是,在对base_facebook.php进行了一些挖掘base_facebook.php ,我注意到方法getCode()实际上使用$_REQUEST从查询参数中检索授权代码。

从PHP手册,$ _REQUEST是

一个关联数组,默认情况下包含$ _GET,$ _POST和$ _COOKIE的内容。

它与$ _GET,$ _ POST或$ _COOKIE非常不同。

根据您的设置,这可能是一个bugger。 所以相反,在base_facebook.php中找到如下所示的函数base_facebook.php getCode()

protected function getCode() {
if (isset($_REQUEST['code'])) {
    if ($this->state !== null &&
            isset($_REQUEST['state']) &&
            $this->state === $_REQUEST['state']) {

        // CSRF state has done its job, so clear it
        $this->state = null;
        $this->clearPersistentData('state');
        return $_REQUEST['code'];
    } else {
        self::errorLog('CSRF state token does not match one provided.');
        return false;
    }
}

return false;
}

并将查询合并到一个新的数组/变量(让我们称之为$code_array ),使用array_merge()包含$_GET$_POST$_COOKIE数组,如下所示:

$code_array = array_merge($_GET,$_POST,$_COOKIE);

您最终得到的是一个包含来自相应请求的所有数据的数组。 只需继续使用函数内的$code_array替换$_REQUEST ,即

\\replace $_REQUEST with $code_array;
if (isset($code_array['code'])) {
if ($this->state !== null &&
        isset($code_array['state']) && 
        $this->state === $code_array['state']) { //...and so on for the rest

这应该很好地完成工作(希望如此)。

可选 - 延长您的访问令牌生命周期

这是可选的,但无论如何我都包含了它。 大多数新应用程序已经拥有长期访问令牌,但为了以防万一,您可以使用$facebook->setExtendedAccessToken(); 转换现有访问令牌的方法。

注意:您必须调用$facebook->setExtendedAccessToken(); 在使用getAccessToken()方法实际获取访问令牌之前。

现在,使用您的代码

$user = $facebook->getUser();
  if($user) {
    try {
    // Just to be sure, add access token to each request
    $facebook->setExtendedAccessToken();
    $access_token = $facebook->getAccessToken();
    // Fetch user details
    $user = $facebook->api('/me?access_token='.$access_token);
    }
//and so on..

结论

将$ _REQUEST分解为$ _GET,$ _ POST和$ _COOKIE(即使它默认包含所有三个)似乎确保我们可以毫不费力地获取SDK设置的cookie。 我说似乎是因为哎呀,我真的不是很自信。

我使用上面的方法让它在我的情况下工作,所以我希望分享一些知识,因为我已经在这个问题上失去了太多的睡眠,并且找不到可行的解决方案。

希望这可以帮助!

编辑:我忘记提及,更改API请求

$user_profile = $facebook->api('/me');

$user_profile = $facebook->api('/'.$user.'?access_token='.$access_token);

这也是我也做过的事情,它起了作用。 :)

也许是因为Facebook PHP SDK不是ajax而且我们使用的是PHP页面,而且我们的服务器加载速度比Facebook的认证过程更快,以回读有效的会话。 Facebook PHP SDK需要的是从我们的应用程序刷新会话验证的页面,这应该内置到Facebook Javascript SDK,但它看起来不是。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM