为什么我的测试应用程序处于无休止的重定向循环中


Why is my test application in an endless redirect loop?

我使用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设置得很好。

我在这里看到了很多关于这个重定向循环的类似问题,但没有一个建议的答案能解决它,而且它们都很旧。这应该在本地主机上工作吗?我是否在Facebook上的应用程序设置中缺少应用程序设置?

更新

因此,如果您使用此处的代码:http://developers.facebook.com/docs/authentication/那么它就起作用了。github上的php-sdk示例完全忽略了这一点,并且不包括您需要检查是否设置了"代码"并生成自己的CSRF令牌的事实。然后,您需要先进行调用以获取访问令牌,然后才能调用Graph API。

此外,SDK的getLoginURL()方法返回一个似乎不起作用的https://URL。如果我制作自己的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方法并使其工作(请记住,我需要它在代理后面工作),那么你就会得到奖励。

许多不同的服务器端Facebook SDK都没有按照Facebook在过去3或4个月里分享的文档和推荐做法来处理身份验证。您在PHP SDK如何使用(或不使用)代码参数中找到了一个很好的例子。还有其他例子,比如直接读取Facebook cookie的SDK,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.");
       }
     ?>

这有几个问题。

  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/'),

并在以后添加参数进行实验。