Как читать / анализировать данные Signed_Request из скрипта регистрации в Php 5.1.6 - PullRequest
2 голосов
/ 03 октября 2011

Я пытаюсь реализовать скрипт регистрации Facebook.

Форма отправляется нормально, а сервер получает подписанный запрос. Однако он не может прочитать / проанализировать подписанный запрос.

Я использовал сценарий, рекомендуемый на странице регистрации https://developers.facebook.com/docs/plugins/registration/ (код ниже), и все, что я вижу для вывода:

содержание подписанного запроса:

Я подтвердил, что подписанный запрос получен. Если я передам это: http://developers.facebook.com/tools/echo?signed_request= Я увижу данные.

Однако на моем сервере со скриптом ниже ничего нет.

Сервер http НЕ https и использует php 5.1.6 (который не поддерживает JSON). Нужно ли устанавливать PHP SDK? Или jsonwrapper? Я пробовал jsonwrapper, но не PHP SDK.

Буду признателен за любую помощь в том, почему подписанный запрос не может быть прочитан.

Код ниже от facebook

<code>    <?php
    include ('jsonwrapper/jsonwrapper.php');


    define('FACEBOOK_APP_ID', 'XXX');
    define('FACEBOOK_SECRET', 'XXX');

    function parse_signed_request($signed_request, $secret) {
    list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

  // decode the data
  $sig = base64_url_decode($encoded_sig);
  $data = json_decode(base64_url_decode($payload), true);

  if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
    error_log('Unknown algorithm. Expected HMAC-SHA256');
    return null;
  }

  // check sig
  $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
  if ($sig !== $expected_sig) {
    error_log('Bad Signed JSON signature!');
    return null;
  }

  return $data;
}

function base64_url_decode($input) {
    return base64_decode(strtr($input, '-_', '+/'));
}

if ($_REQUEST) {
  echo '<p>signed_request contents:</p>';

  $response = parse_signed_request($_REQUEST['signed_request'], 
                                   FACEBOOK_SECRET);
  echo '<pre>';
  print_r($response);
  echo '
'; } еще { echo '$ _REQUEST пусто'; } ?>

вывод

"содержимое подписанного запроса:"

Если я добавлю: print_r ($ _ REQUEST); к сценарию я вижу запрос, но не могу разобрать его

Ответы [ 2 ]

0 голосов
/ 03 октября 2011

Вам не нужен PHP SDK для этого. Это может облегчить это и другие различные вещи, но это не обязательно, если вы хотите выполнить декодирование самостоятельно.

Вы уверены, что у вас есть функция json_decode? Я не думаю, что это обычно часть jsonwrapper.php, поэтому я подозреваю, что ваш скрипт не работает при вызове этой функции. Вы можете использовать следующую функцию в качестве замены, просто измените вызов на usr_json_decode и включите следующее в нижней части вашего скрипта:

function usr_json_decode($json, $assoc=FALSE, $limit=512, $n=0, $state=0, $waitfor=0)
{
  $val=NULL;
  static $lang_eq = array("true" => TRUE, "false" => FALSE, "null" => NULL);
  static $str_eq = array("n"=>"\012", "r"=>"\015", "\\"=>"\\", '"'=>'"', "f"=>"\f", "b"=>"\b", "t"=>"\t", "/"=>"/");
  for (; $n<strlen($json); /*n*/)
    {
    $c=$json[$n];
    if ($state==='"')
      {
      if ($c=='\\')
        {
        $c=$json[++$n];
        if (isset($str_eq[$c]))
          $val.=$str_eq[$c];
        else if ($c=='u')
          {
          $hex=hexdec(substr($json, $n+1, 4));
          $n+=4;
          if ($hex<0x80) $val .= chr($hex);
          else if ($hex<0x800) $val.=chr(0xC0+$hex>>6).chr(0x80+$hex&63);
          else if ($hex<=0xFFFF) $val.=chr(0xE0+$hex>>12).chr(0x80+($hex>>6)&63).chr(0x80+$hex&63);
          }
        else
          $val.="\\".$c;
        }
      else if ($c=='"') $state=0;
      else $val.=$c;
      }
    else if ($waitfor && (strpos($waitfor, $c)!==false))
      return array($val, $n);
    else if ($state===']')
      {
      list($v, $n)=usr_json_decode($json, $assoc, $limit, $n, 0, ",]");
      $val[]=$v;
      if ($json[$n]=="]") return array($val, $n);
      }
    else
      {
      if (preg_match("/\s/", $c)) { }
      else if ($c=='"') $state='"';
      else if ($c=="{")
        {
        list($val, $n)=usr_json_decode($json, $assoc, $limit-1, $n+1, '}', "}");
        if ($val && $n) $val=$assoc?(array)$val:(object)$val;
        }
      else if ($c=="[")
        list($val, $n)=usr_json_decode($json, $assoc, $limit-1, $n+1, ']', "]");
      elseif (($c=="/") && ($json[$n+1]=="*"))
        ($n=strpos($json, "*/", $n+1)) or ($n=strlen($json));
      elseif (preg_match("#^(-?\d+(?:\.\d+)?)(?:[eE]([-+]?\d+))?#", substr($json, $n), $uu))
        {
        $val = $uu[1];
        $n+=strlen($uu[0])-1;
        if (strpos($val, ".")) $val=(float)$val;
        else if ($val[0]=="0") $val=octdec($val);
        else $val=(int)$val;
        if (isset($uu[2])) $val*=pow(10, (int)$uu[2]);
        }
      else if (preg_match("#^(true|false|null)\b#", substr($json, $n), $uu))
        {
        $val=$lang_eq[$uu[1]];
        $n+=strlen($uu[1])-1;
        }
      else
        {
        return $waitfor ? array(NULL, 1<<30) : NULL;
        }
      }
    if ($n===NULL) return NULL;
    $n++;
    }
  return ($val);
}

Кстати, это должно быть очень легко отследить, используя журнал ошибок, включив дополнительную отладку и добавив некоторые операторы echo или var_dump при необходимости.

0 голосов
/ 03 октября 2011

У меня было нечто подобное с подписанным запросом, возвращающимся пустым.В вашем приложении убедитесь, что вы сначала загрузили и включили php sdk из http://developers.facebook.com/docs/reference/php/. Затем добавьте

 require_once("facebook.php");

в ваш скрипт вверху или туда, куда вы его загрузили.Теперь в настройках приложения для приложения в Facebook убедитесь, что в вашем URL-адресе приложения указан www или нет.Например: в приложении он указывает на example.com/index.php?tab=test, но когда вы помещаете его в браузер, всегда появляется www, example.com / index.php? Tab = test.Не считая www, можно все испортить.

РЕДАКТИРОВАТЬ - РАБОТАЕТ ДЛЯ МЕНЯ

<code>    <?php
    #error_reporting(E_ALL);

        include ('{{PATH TO facebook.php}}');


        $appapikey = 'xxxx';
        $appsecret = 'xxxx';
        $facebook = new Facebook($appapikey, $appsecret);

    function parsePageSignedRequest() {
        if (isset($_REQUEST['signed_request'])) {
          $encoded_sig = null;
          $payload = null;
          list($encoded_sig, $payload) = explode('.', $_REQUEST['signed_request'], 2);
          $sig = base64_decode(strtr($encoded_sig, '-_', '+/'));
          $data = json_decode(base64_decode(strtr($payload, '-_', '+/'), true));
          return $data;
        }
        return false;
      }
      function parse_signed_request($signed_request, $secret) {
          list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

          // decode the data
          $sig = base64_url_decode($encoded_sig);
          $data = json_decode(base64_url_decode($payload), true);

          if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
            error_log('Unknown algorithm. Expected HMAC-SHA256');
            return null;
          }

          // check sig
          $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
          if ($sig !== $expected_sig) {
            error_log('Bad Signed JSON signature!');
            return null;
          }

          return $data;
        }
        function base64_url_decode($input) {
          return base64_decode(strtr($input, '-_', '+/'));
        }

    if (isset($_REQUEST['signed_request'])) {
      echo '<p>signed_request contents:</p>';

      $response = parse_signed_request($_REQUEST['signed_request'], 
                                       $appsecret);
      echo '<pre>';
      print_r($response);
      echo '
';} else {echo '$ _REQUEST is empty';}?> function getDefinedVars ($ varList, $ excludeList) {$ temp1 = array_values ​​(array_diff (array_keys ($ varList), $ excludeList));$ temp2 = array ();while (list ($ key, $ value) = each ($ temp1)) {global $$ value;$ temp2 [$ value] = $$ value;} return $ temp2;}

Чтобы просмотреть все переменные SYSTEM (кроме глобальных / файлов / файлов cookie / post / get), чтобы убедиться, что подписанный запрос пройден, вы можете использовать этот фрагмент кода

<code>      /**
       * @desc   holds the variable that are to be excluded from the list.
       *         Add or drop new elements as per your preference.
       * @var    array
       */
      $excludeList = array('GLOBALS', '_FILES', '_COOKIE', '_POST', '_GET', 'excludeList');

      //some dummy variables; add your own or include a file.
      $firstName = 'kailash';
      $lastName = 'Badu';
      $test = array('Pratistha', 'sanu', 'fuchhi');

      //get all variables defined in current scope
      $varList = get_defined_vars();

      //Time to call the function
      print "<pre>";
      print_r(getDefinedVars($varList, $excludeList));
      print "
";
...