簡體   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