2012-02-29 77 views
3

我使用PHP SDK版本3.1.1爲了簡單地調用Graph API。我在本地運行它http://local.fb-sandbox。 Facebook應用程序設置的網站URL設置爲http://local.fb-sandbox/爲什麼我的測試應用程序處於無限重定向循環?

我重定向到Facebook登錄頁面,然後在頁面請求我的同意,我去http://local.fb-sandbox但隨後的應用程序進入重定向循環URL之間,如:

http://local.fb-sandbox/?state=e9c091bb61afe08139af4e3b153a1e9e&code=AQBDJ4yMWVOIrukx6nRkxhNbnPH9nX6OvuqOWhVJEAgLkq6Lz27iq_-B6AIAGQ_cOpBIZktCPLLs_G5Hpt8QO5PRhDUN8l-Yu3JuT0YTzwVQiAqBlgutgia60lRT-ZzE3IHguStHq4gtuPQYJh423TBer-mB8BsqERvNsoF1L4NNe90WAWU8--MFAU3Oc4eeXyI#_=_ 

https://www.facebook.com/dialog/oauth?client_id=375741229103324&redirect_uri=http%3A%2F%2Flocal.fb-sandbox%2F%3Fstate%3Dccd13778febb68d3eb1f4763a99b2ace%26code%3DAQBFegtkch4m34-2F9KMKgScrPhWzI0qeKJlvnM6uAD81BYm2xakv0S7DEbUrNwlECrgth5-YHdT8IR_vCBzW29QMh3ecOiiEk7P03wQG2V2gaxAUsMqOOZvTl_Oq3SefiLn9BvBAPQSGXQdRSZBVdsUqDT1aZ430Lcx8Ic6axaHSyHwlkkNK5EjRhYdkjYYz0YmENk64kRf4tvmX4WrH6f4&state=19a3862962dd0422628eb7c28a832380&scope=email%2Cread_stream%2Cpublish_stream%2Cuser_photos%2Cuser_videos&fbconnect=1#_=_ 

我在腳本的頂部調用了session_start(),並嘗試使用和不使用它。 PHP cookie設置正常。

我在這裏看到很多關於這個重定向循環的類似問題,但是沒有一個建議的答案解決了它,它們都很老。應該在localhost上工作嗎? AM我在Facebook上的應用程序設置中缺少應用程序設置?

UPDATE

如此看來,如果你從這裏使用代碼:http://developers.facebook.com/docs/authentication/然後它工作。 github上的php-sdk例子完全忽略了這一點,並且不包括你需要檢查是否設置了'code'並生成自己的CSRF令牌的事實。然後您需要撥打電話來獲取訪問令牌,然後才能調用Graph API。

另外,SDK的getLoginURL()方法返回一個看起來不起作用的https:// URL。如果我製作自己的網址,那麼它可以工作。

工作代碼:

if(empty($code)) { 
    $_SESSION['state'] = md5(uniqid(rand(), TRUE)); 
$login_url_params = array(
     'scope' => 'email,read_stream,publish_stream,user_photos,user_videos', 
     'fbconnect' => 1, 
     'redirect_uri' => 'http://local.fb-sandbox/', 
'state'=>$_SESSION['state'] 
    ); //using this array via the sdk does not work 

    $dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" 
     . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state=" 
     . $_SESSION['state']; //this url works 

    //var_dump($dialog_url);echo "<br />"; 
    $login_url = $facebook->getLoginUrl(); 
    //var_dump($login_url); 
    header("Location:{$dialog_url}");//works 
    //header("Location:{$login_url}");//does not work 
    exit; 
} 



if($_REQUEST['state'] == $_SESSION['state']) { 
$token_url = "https://graph.facebook.com/oauth/access_token?" 
     . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url) 
     . "&client_secret=" . $app_secret . "&code=" . $code; 
$aContext = array(
    'http' => array(
     'proxy' => 'tcp://xxxx0:80', 
     'request_fulluri' => true, 
    ), 
); 
$cxContext = stream_context_create($aContext); 
     $response = file_get_contents($token_url, FALSE, $cxContext); 

     $params = null; 
     parse_str($response, $params); 

     $graph_url = "https://graph.facebook.com/me?access_token=" . $params['access_token']; 

     $user = json_decode(file_get_contents($graph_url, FALSE, $cxContext)); 
     //var_dump($user);exit; 
} 

//var_dump($user);exit; 
    return $app->render('test.html',array('myvar', $user)); 
    exit(); 

注意,我要通過代理,因此必須設置爲的file_get_contents上下文()調用。

如果任何人都可以將我的代碼轉換爲使用正確的SDK方法並使其工作(注意我需要它在代理後面工作),那麼您將獲得賞金。

+0

有同樣的問題;僅在用戶第一次使用應用時發生。 Php給你和你一樣的錯誤。 – sgb 2012-03-01 15:44:10

+0

** var_dump($ user); **輸出是什麼? – 2012-03-07 04:08:59

+0

@GilBirman:輸出'0' – codecowboy 2012-03-07 08:21:54

回答

5

許多各種服務器端Facebook SDK不能根據Facebook在過去的3到4個月內共享的文檔和推薦做法來處理身份驗證。您在PHP SDK如何使用(或不使用)代碼參數方面找到了一個很好的例子。還有其他一些例子,比如Facebook直接閱讀Facebook cookies,Facebook工程師告訴開發者不應該這樣做,因爲Cookie只是「實現細節」,並不是Facebook之外的開發人員應該建立依賴關係。

我不知道,你在你的工作代碼示例得到了代碼,但我無法找到包括參數,如fbconnect=1

所以鑑於SDK不實施身份驗證按照Facebook的建議,任何支持和文檔,而Facebook已經提供了文檔中一個完整的PHP實現,我建議你只使用Facebook的版本提供,複製和粘貼在這裏從這個網頁http://developers.facebook.com/docs/authentication/您參考:

 <?php 

     $app_id = "YOUR_APP_ID"; 
     $app_secret = "YOUR_APP_SECRET"; 
     $my_url = "YOUR_URL"; 

     session_start(); 
     $code = $_REQUEST["code"]; 

     if(empty($code)) { 
     $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection 
     $dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" 
      . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state=" 
      . $_SESSION['state']; 

     echo("<script> top.location.href='" . $dialog_url . "'</script>"); 
     } 

     if($_REQUEST['state'] == $_SESSION['state']) { 
     $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); 

     $graph_url = "https://graph.facebook.com/me?access_token=" 
      . $params['access_token']; 

     $user = json_decode(file_get_contents($graph_url)); 
     echo("Hello " . $user->name); 
     } 
     else { 
     echo("The state does not match. You may be a victim of CSRF."); 
     } 

    ?> 
+0

感謝帕特。你會建議完全避免使用PHP-SDK嗎? – codecowboy 2012-03-12 09:49:45

+1

我主要使用.NET工作,所以我沒有很多第一手的PHP SDK經驗。我會告訴你,我使用C#SDK只是在我使用我自己的代碼進行認證處理時進行api調用,這是對Facebook推薦的服務器端OAuth實現的直接調整 - 一旦你採用了有時間閱讀它。我完全忽略了Facebook的cookie。 – 2012-03-12 13:34:28

+0

將使用file_get_contents發送請求時將auth令牌和其他請求params加密嗎? – 2013-10-15 19:44:52

1

這有幾個問題。

  1. 您的redirect_uri應該像http://local.fb-sandbox/。最後必須有一個斜線 - 無論是在developers.facebook.com的代碼和Facebook應用程序設置中。

  2. 你必須在redirect_uri上使用uurlencode。

  3. 不要在redirect_uri中使用$ _SERVER ['REQUEST_URI']。通過處理app_data或根據用戶旅程添加它們,找到一種方法來添加所需的任何參數。

作爲開始替換這一行:與後添加參數

'redirect_uri' => urlencode('http://local.fb-sandbox/'), 

和實驗。

+0

我不明白你在說什麼參數... – 2012-02-29 12:52:22

+0

代碼是由facebook在登錄成功時返回的,爲什麼你將它添加到登錄網址? – 2012-02-29 13:13:45

+0

這些建議沒有解決問題。我已經刪除了可能具有誤導性的評論。我試圖更換該行,但仍然遇到問題。我已經更新了上面的代碼。任何其他想法? – codecowboy 2012-03-01 09:49:43