Почему мое тестовое приложение находится в бесконечном цикле перенаправления?

Я использую 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() в верхней части моего скрипта, и я пробовал как с ним, так и без него. Файл cookie PHP устанавливается нормально.

Я видел здесь много подобных вопросов относительно этого цикла перенаправления, но ни один из предложенных ответов не разрешил его, и все они довольно старые. Должно ли это работать на локальном хосте? Я пропустил настройку приложения в настройках приложения на Facebook?

ОБНОВЛЕНИЕ

Таким образом, если вы используете код отсюда: http://developers.facebook.com/docs/authentication/ тогда все работает. Пример php-sdk на github полностью игнорирует это и не включает тот факт, что вам нужно проверить, установлен ли «код», и сгенерировать свой собственный токен CSRF. Затем вам нужно сделать вызов, чтобы получить токен доступа, прежде чем вы сможете сделать вызов API Graph.

Кроме того, метод SDK getLoginURL() возвращает URL-адрес 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 и заставить его работать (учитывая, что мне нужно, чтобы он работал за прокси-сервером), вы получите награду.


person codecowboy    schedule 29.02.2012    source источник
comment
Имея ту же проблему; происходит только при первом входе пользователя в приложение. Php выдает ту же ошибку, что и вы.   -  person sgb    schedule 01.03.2012
comment
что выводит var_dump($user);?   -  person Gil Birman    schedule 07.03.2012
comment
@GilBirman: выводит '0'   -  person codecowboy    schedule 07.03.2012
comment
так как вам интересно, вы пытались проверить переменную $_REQUEST, если она содержит параметр state? кажется, что $_REQUEST['state'] всегда равно нулю. И как выглядит ваш полный htaccess?   -  person ifaour    schedule 07.03.2012
comment
Состояние и код находятся в $_REQUEST. Я добавил свой .htaccess. Я думаю, что исключил это как причину, хотя   -  person codecowboy    schedule 07.03.2012
comment
у вас есть URL-адрес холста, настроенный для приложения? это то же самое? Кроме того (я не знаю об этом, но проверяю), уверены ли вы, что приложения facebook могут работать по URL-адресам, недоступным для них?   -  person mishu    schedule 07.03.2012
comment
Сейчас он работает - см. Последнее обновление в моем вопросе. У меня установлен «URL-адрес сайта», и он работает на локальном хосте.   -  person codecowboy    schedule 07.03.2012


Ответы (2)


Многие из различных SDK Facebook на стороне сервера не поддерживают аутентификацию в соответствии с документацией и рекомендуемыми практиками, которыми Facebook поделился за последние 3 или 4 месяца. Вы нашли хороший пример этого в том, как PHP SDK использует (или не использует) параметр кода. Есть и другие примеры, когда SDK напрямую считывают файлы cookie Facebook, и инженеры 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.");
       }

     ?>
person Pat James    schedule 11.03.2012
comment
Спасибо Пэт. Вы бы порекомендовали полностью отказаться от PHP-SDK? - person codecowboy; 12.03.2012
comment
Я работаю в основном с .NET, поэтому у меня нет большого опыта работы с PHP SDK. Я скажу вам, что я использую C# SDK только для выполнения вызовов API после того, как аутентификация выполняется с использованием моего собственного кода, который является прямой адаптацией реализации OAuth на стороне сервера, рекомендованной Facebook. пора ее прочитать. Я полностью игнорирую файлы cookie Facebook. - person Pat James; 12.03.2012
comment
будет ли зашифрован токен аутентификации и другие параметры запроса при использовании file_get_contents для отправки запроса? - person Jayapal Chandran; 15.10.2013

Есть несколько проблем с этим.

  1. Ваш redirect_uri должен выглядеть как http://local.fb-sandbox/ . В конце должна быть косая черта — как в коде, так и в настройках приложения facebook на сайте developer.facebook.com.

  2. Вы должны использовать uurlencode в файле redirect_uri.

  3. Не используйте $_SERVER['REQUEST_URI'] в redirect_uri. Найдите способ добавить любые необходимые параметры, обработав app_data или добавив их в зависимости от пути пользователя.

Для начала замените эту строку:

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

и поэкспериментируйте с добавлением параметров позже.

person Alexander Nenkov    schedule 29.02.2012
comment
код возвращается facebook при успешном входе в систему, зачем вам добавлять его в URL-адрес входа? - person Alexander Nenkov; 29.02.2012
comment
Эти предложения не решили проблему. Я удалил потенциально вводящие в заблуждение комментарии. Я попытался заменить эту строку и все еще получаю проблему. Я обновил код выше. Любые другие идеи? - person codecowboy; 01.03.2012
comment
Вы должны использовать uurlencode для redirect_uri ‹‹ Я не думаю, что это правда. - person Gil Birman; 07.03.2012