Я пытаюсь реализовать скрипт регистрации 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 contents:"
Если я добавлю: print_r ($ _ REQUEST); к скрипту я вижу запрос, но не могу его разобрать
Для этого вам не нужен PHP SDK. Это может облегчить это и различные другие вещи, но это не обязательно, если вы хотите сделать декодирование самостоятельно.
Вы уверены, что у вас есть функция json_decode? Я не думаю, что это обычно часть jsonwrapper.php, поэтому я подозреваю, что ваш скрипт рушится на этот вызов функции. Вы можете использовать следующую функцию в качестве замены, просто измените вызов на usr_json_decode
и 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); }
Кстати, это должно быть очень легко отследить, используя ваш журнал ошибок, включив дополнительную отладку и добавив некоторые var_dump
echo
или var_dump
по необходимости.
У меня было что-то подобное, когда подписанный запрос вернулся. В своем приложении убедитесь, что вы сначала загрузили и включили 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 может испортить это.
<?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; }
Чтобы просмотреть все переменные SYSTEM (кроме globals / files / 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>";