我已經搜刮了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);
}
}
希望這會有所幫助。
這也是與PHP 3.1.1 SDK –
這幫助我更好地瞭解如何做到這一點!通過javascript與fb js sdk訪問令牌創建cookie並在fb php sdk中檢索它肯定有效 – Patareco