如何在Php 5.1.6中从注册脚本中读取/解析Signed_Request的数据

时间:2011-10-03 06:00:45

标签: php facebook registration facebook-php-sdk

我正在尝试实施Facebook注册脚本。

表单已提交正常,服务器正在接收已签名的请求。但是,它无法读取/解析签名的请求。

我使用了注册页面https://developers.facebook.com/docs/plugins/registration/上建议的脚本(下面的代码),我看到的输出结果是:

signed_request内容:

我已经确认正在收到signed_Request。如果我将其传递给:http://developers.facebook.com/tools/echo?signed_request=我会看到数据。

然而,在我的服务器上,脚本下面没有任何内容。

服务器是http NOT https并使用php 5.1.6(它没有一些JSON支持)我是否需要安装PHP SDK?还是jsonwrapper?我已经尝试过jsonwrapper而不是PHP SDK。

有关无法阅读signed_request的原因的任何帮助将不胜感激。

以下来自facebook的代码

    <?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 '</pre>';

} else {
  echo '$_REQUEST is empty';
}
?> 

输出

“signed_request内容:”

如果我添加:  的print_r($ _ REQUEST);到脚本我看到了请求,但无法解析它

2 个答案:

答案 0 :(得分:0)

我有一些类似的签名请求回来了。在您的应用程序上,请确保首先从http://developers.facebook.com/docs/reference/php/下载并包含php sdk。接下来添加

 require_once("facebook.php");

到顶部的脚本或上传到的脚本。现在,在应用程序的应用程序设置中,在Facebook中,确保您的应用程序的URL中包含www。例如:在应用程序中,您将其指向example.com/index.php?tab=test,但是当您将其放入浏览器时,它总是会出现www,example.com / index.php?tab = test。不包括www可能搞砸了。

编辑 - 为我工作

    <?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 '</pre>';

    } else {
      echo '$_REQUEST is empty';
    }
    ?> 
    <iframe src="https://www.facebook.com/plugins/registration.php?
                 client_id=134219456661289&
                 redirect_uri={{YOUR SITE URL ENCODED}}&fields=name,birthday,gender,location,email"
            scrolling="auto"
            frameborder="no"
            style="border:none"
            allowTransparency="true"
            width="100%"
            height="330">
    </iframe>

      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;
      }

要查看所有系统变量(全局/文件/ cookies / post / get除外)以确保传递签名请求,您可以使用此代码片段

      /**
       * @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 "</pre>";

答案 1 :(得分:0)

您不需要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);
}
但是,BTW应该很容易使用您的错误日志进行跟踪,启用额外的调试并根据需要添加一些echovar_dump语句。