3

我已經搜刮了StackOverflow,甚至向Facebook提交了一個bug,但沒有任何幫助。我花了堅實的40多個小時打了下來。我相信它是FB.INIT和PHP訪問令牌之間的衝突,當服務器有很重的.htaccess Mod重寫將url更改爲有效的查詢字符串。我把它寫成了一個bug,但Facebook認爲這是一個用戶問題。我甚至在他們的回答中使用了代碼,但仍然存在竊聽。Facebook JS SDK和PHP SDK訪問令牌衝突

這是原始問題。 在我的測試網站上,我可以使用JS SDK獲得PHP SDK以便正常工作。 都允許登錄和協調工作相互溝通。沒有問題 當瀏覽網頁或執行所有功能我即將更新客戶端 與。

現在我試圖安裝新的OAuth更新到我的客戶站點與沉重 .htaccess國防部重寫。我的測試網站沒有Mod ReWrites。

起初你可以用PHP登錄就好了。但是一旦您訪問網站中的另一個 頁面,您將失去Access令牌並帶有流行錯誤:必須使用一個 活動訪問令牌來查詢有關當前用戶的信息。

這是固定通過檢查,看看是否PHP API失敗,然後用 的file_get_contents命令從Facebook自己的授權頁面採取 (反對:https://graph.facebook.com/oauth/access_token)和復位 訪問令牌。這工作。但是,這導致FB.init失敗,並返回 響應錯誤:必須使用活動訪問令牌來查詢有關當前用戶的信息 。回調由FB.api('/我')

因此,爲了解決這個問題,我不得不將PHP的訪問令牌傳入SESSION並將 放在我的api調用中。像這樣,FB.api('/ me /?access_token =')。這工作。所以,現在我的網站通過支配PHP與Facebook的 工作,JS是次要的。

當前問題:如果用戶訪問該站點並且未登錄到標準的 PHP Facebook函數並使用使用FB JS SD的函數;該網站提示 JS登錄具有該網站功能的適當權限。用戶 接受並登錄。從JS的角度來看,一切都很好。 console.log轉儲告訴我這個從一頁到另一頁的情況。

的問題:PHP不會從 JS SDK設置cookie承認ACCESS_TOKEN,也不會收到的file_get_contents一個cookie(踢回 失敗的HTTP請求400)。所以當用戶通過JS登錄時, PHP將不會接受他們的登錄並仍然顯示PHP getLoginUrl函數。

當在PHP facebook對象上執行var_dump時,我們看到所有字段 都包含數據;代碼,狀態,access_token,算法等等。但是,當執行每個頁面上 $ facebook-> API(「/我」)(這是上面的成功) 我們收到的錯誤:一個積極的訪問令牌必須用於查詢當前用戶的信息 。

我的結論:有一個不匹配的代碼生成基於JS的感知URL 和PHP的實際URL。在哪裏更容易強制JS訪問PHP訪問 令牌同樣不能完成的PHP被JS統治。

下面是每個頁面上的PHP代碼。

$app_id = 'APP_ID'; 
$app_secret = 'APP_SEC'; 
$my_url = 'http://'.$_SERVER['HTTP_HOST']; 
$facebook = new Facebook(array(
    'appId' => $app_id, 
    'secret' => $app_secret, 
)); 
$_SESSION[fbappID] = $facebook->getAppId(); 
$_SESSION[fbaccTok] = $facebook->getAccessToken(); 
$sigReq = $facebook->getSignedRequest(); 
$code = $sigReq[code]; 
$userID = $facebook->getUser(); 
if($userID) 
{ 
    try { 
    $user_profile = $facebook->api('/me'); 
    } catch (FacebookApiException $e) { 
    error_log($e); 
    $token_url = "https://graph.facebook.com/oauth/access_token?" 
     . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url) 
     . "&client_secret=" . $app_secret . "&code=" . $code; 
    $response = file_get_contents($token_url); 
    $params = null; 
     parse_str($response, $params); 
     if($params[access_token]!="") 
    { 
     $facebook->setAccessToken($params[access_token]); 
     $_SESSION[fbaccTok] = $facebook->getAccessToken(); 
    } 
    try{ 
     $user_profile = $facebook->api('/me'); 
    }catch(FacebookApiException $e) { 
     error_log($e); 
     $userID = null; 
    } 
    } 
} 
if($userID) 
{ 
    $user_profile = $facebook->api('/me'); 
    $logout = $facebook->getLogoutUrl(); 
} 
else 
{ 
    $login = "<a href='".$facebook->getLoginUrl()."'>Log In with Facebook</a>"; 
} 

JavaScript的使用:

<script> 
FB.init({ 
    appId : '$_SESSION[fbappID]', 
status : true, 
    cookie : true, 
    xfbml : true, 
    oauth : true 
    }); 
    FB.api('me/permissions/?access_token=<?php print $_SESSION[fbaccTok]? 
    >',function(response){console.log(response)}); 
</script> 

答:

下面是答案:要允許JavaScript是主要入境點。你不能擁有兩個。您必須選擇一個,PHP或JavaScript,並使其成爲強制其他訪問令牌的主導。這裏是Javascript:

window.fbAsyncInit = function() { 

    FB.init({ 
     appId : '12345', 
     channelURL : '/channel.php', 
     status : true, 
     cookie : true, // enable cookies to allow the server to access the session 
     xfbml : true, // parse XFBML 
     oauth : true //enables OAuth 2.0 
    }); 
FB.getLoginStatus(function(response){ 
    if(response.authResponse){ 
     FB.accessToken = ; 
     createCookie('fbToken',response.authResponse.accessToken,.1); 
     createCookie('fbID',response.authResponse.userID,.1); 
    } 
    }); 
FB.Event.subscribe('auth.login', function(response) { 
    createCookie('fbToken',response.authResponse.accessToken,.1); 
    createCookie('fbID',response.authResponse.userID,.1); 
    createCookie('fbLogin',1,30); 
    window.location.reload(); 

}); 
FB.Event.subscribe('auth.logout', function() { 
     eraseCookie('fbLogin'); 
     eraseCookie('fbToken'); 
     eraseCookie('evFB.uid'); 
}); 
} 

createCookie和eraseCookie是可以通過網絡找到的cookie功能。這是粗略的代碼而不是精煉的。基本上我創建了自己的Cookie來傳遞信息。由於FB JS SDK在登錄和註銷時刷新頁面,我可以在PHP接管頁面刷新之前刪除並創建cookie或修改它們。

現在這裏是強制JS cookie訪問令牌的PHP。

require_once("/facebook.php"); 

$facebook = new Facebook(array(
    'appId' => $app_id, 
    'secret' => $app_secret, 
)); 
$my_url = $facebook->returnGetUrl(); 
$_SESSION[fbaccTok] = (isset($_COOKIE[fbToken]))?$_COOKIE[fbToken]:$facebook->getAccessToken(); 


$sigReq = $facebook->getSignedRequest(); 
$code = ($_REQUEST[code]=='')?$sigReq[code]:$_REQUEST[code]; 

$GLOBALS[fbUser]= $facebook->getUser(); 

if(isset($_COOKIE[fbLogin])) 
{ 
    if($_COOKIE[fbLogin]==1) 
    { 
     $GLOBALS[fbUser] = $facebook->getUser(); 
     //print $GLOBALS[fbUser]; 
    } 
    else 
    { 
     $GLOBALS[fbUser] = null; 
    } 
} 
else 
{ 
    $GLOBALS[fbUser] = null; 
} 
if($GLOBALS[fbUser] && $_COOKIE[fbToken]) 
{ 
    $GLOBALS[fbArray] = array(
     'access_token' => $_COOKIE[fbToken] 
     ); 
     try { 
      $GLOBALS[fbUserProfile] = $facebook->api('/me','GET',$GLOBALS[fbArray]); 
      //print_r($GLOBALS[fbUserProfile]); 


     } catch (FacebookApiException $e) { 
      error_log($e); 

     } 
} 

希望這會有所幫助。

+0

這也是與PHP 3.1.1 SDK –

+0

這幫助我更好地瞭解如何做到這一點!通過javascript與fb js sdk訪問令牌創建cookie並在fb php sdk中檢索它肯定有效 – Patareco

回答

0

如果作品,未經國防部重寫但與國防部重寫,那麼這是問題,

你可以做的是創造另一個Facebook的測試應用程序和託管在一個單獨的服務器上,而不國防部重寫,然後逐漸添加模塊,一次重寫1,直到問題發生,看看是哪一個造成的。

+0

我遇到了同樣的問題,我沒有任何mod重寫集 – Matrym

+0

我已更新我的問題以包含答案。 –

+1

@V Rodg您應該將其添加爲回答而不是問題中的內容,但現在仍標記爲未回答 – xorinzor

相關問題