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

Php 为什么我的测试应用程序处于无止境的重定向循环中?,php,facebook,oauth,facebook-php-sdk,Php,Facebook,Oauth,Facebook Php Sdk,我使用PHPSDK版本3.1.1对Graph API进行简单调用。我在本地运行它。facebook应用程序设置将网站URL设置为 我被重定向到facebook登录页面,然后转到请求我权限的页面,但应用程序随后进入URL之间的重定向循环,如: http://local.fb-sandbox/?state=e9c091bb61afe08139af4e3b153a1e9e&code=AQBDJ4yMWVOIrukx6nRkxhNbnPH9nX6OvuqOWhVJEAgLkq6Lz27iq_-B

我使用PHPSDK版本3.1.1对Graph API进行简单调用。我在本地运行它。facebook应用程序设置将网站URL设置为

我被重定向到facebook登录页面,然后转到请求我权限的页面,但应用程序随后进入URL之间的重定向循环,如:

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

我在脚本的顶部调用了session_start(),并尝试了使用和不使用它。PHP cookie正在设置为良好状态

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

更新

因此,如果您使用这里的代码:那么它就工作了。github上的PHPSDK示例完全忽略了这一点,并且不包括您需要检查是否设置了“代码”并生成自己的CSRF令牌这一事实。然后,在能够调用Graph API之前,需要进行调用以获取访问令牌

此外,SDK的getLoginURL()方法返回一个https://URL,该URL似乎不起作用。如果我设计了自己的URL,那么它就会工作

工作代码:

if(空($code)){
$_SESSION['state']=md5(uniqid(rand(),TRUE));
$login\u url\u params=数组(
“范围”=>“电子邮件、阅读流、发布流、用户照片、用户视频”,
“fbconnect”=>1,
'重定向\u uri'=>'http://local.fb-sandbox/',
'state'=>$\u会话['state']
);//通过sdk使用此数组不起作用
$dialog_url=”http://www.facebook.com/dialog/oauth?client_id=" 
.$app\u id.&redirect\u uri=“.urlencode($my\u url)。”&state=”
.$\u会话['state'];//此url有效
//变量转储($dialog\u url);回显“
”; $login_url=$facebook->getLoginUrl(); //变量转储($login\u url); 标题(“位置:{$dialog_url}”);//有效 //标头(“位置:{$login_url}”);//不起作用 出口 } if($\u请求['state']=$\u会话['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=数组( “http'=>数组( '代理'=>'tcp://xxxx0:80', 'request_fulluri'=>true, ), ); $cxContext=stream\u context\u create($aContext); $response=file\u get\u contents($token\u url,FALSE,$cxContext); $params=null; parse_str($response,$params); $graph_url=”https://graph.facebook.com/me?access_token=“$params['access_token']; $user=json_decode(文件获取内容($graph_url,FALSE,$cxContext)); //变量转储($user);退出; } //var_dump($user);出口 返回$app->render('test.html',数组('myvar',$user)); 退出();
请注意,我正在使用代理,因此必须为文件\u get\u contents()调用设置上下文


如果有人可以将我的代码转换为使用适当的SDK方法并使其工作(请记住,我需要它在代理后工作),那么您将获得奖励。

这有几个问题

  • 你的重定向uri应该是这样的。在developers.facebook.com的代码和facebook应用程序设置中,末尾必须有一个斜杠


  • 您必须在重定向uri上使用uurlencode

  • 不要在重定向URI中使用$\u SERVER['REQUEST\u URI']。通过处理app_数据或根据您的用户旅程添加参数,找到添加所需参数的方法

  • 首先,更换该行:

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

    然后尝试添加参数。

    许多服务器端Facebook SDK都没有按照Facebook在过去3到4个月内共享的文档和推荐做法处理身份验证。PHP SDK如何使用(或不使用)代码参数就是一个很好的例子。还有其他一些例子,比如SDK直接读取Facebook cookies,Facebook工程师告诉开发者他们不应该这样做,因为cookies只是“一个实现细节”,而不是Facebook以外的开发者应该依赖的东西

    我不确定您在工作代码示例中从何处获得该代码,但我找不到任何支持包含参数,例如
    fbconnect=1

    因此,鉴于SDK没有按照Facebook的建议和文档实施身份验证,并且Facebook在其文档中提供了完整的PHP实现,我建议您只使用Facebook提供的版本,复制并粘贴在此处,供您在本页面中参考:

    
    
    登录成功后facebook返回代码,为什么要将其添加到登录url?这些建议没有解决问题。我已经删除了潜在的误导性评论。我已经试着换了那条线,但还是出了问题。我已经更新了上面的代码。还有其他想法吗?“你必须在重定向uri上使用uurlencode”有同样的问题;仅在用户首次验证应用程序时发生。Php给了我和你一样的错误;输出?@GilBirman:输出“0”既然您想知道,您是否尝试检查
    $\u REQUEST
    变量是否包含
    state
    参数?似乎
    $\u请求['state']
    总是空的。您的完整
    htaccess
    外观如何?状态和代码在$\u请求中。我已经添加了我的.htaccess。我想我已经排除了这个原因,谢谢帕特。您是否建议完全避免使用PHP-SDK?我主要使用.NET,因此我对PHP-SDK没有太多的第一手经验。我将告诉您,我使用C#SDK只是为了在使用自己的代码(即di)处理身份验证后进行api调用
    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();
    
    'redirect_uri' => urlencode('http://local.fb-sandbox/'),
    
         <?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.");
           }
    
         ?>