dongzengzai4567 2012-02-29 12:11
浏览 92
已采纳

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

I am using the PHP SDK Version 3.1.1 in order to make a simple call to the Graph API. I am running it locally at http://local.fb-sandbox. The facebook application settings have the site URL set to http://local.fb-sandbox/.

I am redirected to the facebook login page and then to the page requesting my permission when I go to http://local.fb-sandbox but the application then goes into a redirect loop between a URL like:

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

and

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#_=_

I have a call to session_start() at the top of my script and have tried both with and without it. The PHP cookie is being set fine.

I've seen a lot of similar questions on here regarding this redirection loop but none of the suggested answers resolved it and they are all quite old. Should this work on localhost? AM I missing an application setting in the app settings on Facebook?

UPDATE

So it seems that if you use the code from here: http://developers.facebook.com/docs/authentication/ then it works. The php-sdk example on github completely ignores this and does not include the fact that you need to check whether 'code' is set and generate your own CSRF token. You then need to make a call to grab an access token before being able to make a call to the Graph API.

Also, the SDK's getLoginURL() method returns an https:// URL which doesn't seem to work. If I craft my own URL then it works.

WORKING CODE:

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();

Note that I am going through a proxy so have to set a context for the file_get_contents() calls.

If anyone can convert my code to use the proper SDK methods and get it working (bearing in mind that I need it to work behind a proxy) then you'll get the bounty.

  • 写回答

2条回答 默认 最新

  • douzi9744 2012-03-11 21:42
    关注

    Many of the various server-side Facebook SDKs do not handle authentication in accordance with the documentation and recommended practices Facebook has shared over the last 3 or 4 months. You found one good example of this in how the PHP SDK uses (or doesn't use) the code parameter. There are other examples such SDKs directly reading the Facebook cookies, something Facebook engineers tell developers they should not do since the cookies are just "an implementation detail" and not something developers outside of Facebook should be building dependencies on.

    I am not sure where you got that code in your working code example, but I couldn't find any support for including parameters such as fbconnect=1

    So given that the SDK is not implementing authentication as per Facebook recommendations and documentation, and that Facebook has provided a complete PHP implementation in their documentation, I recommend you just use the version Facebook provides, copy and pasted here for your reference from this page 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条)

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘