我正在使用PHP SDK 3.1.1版来简单调用Graph API。我在http://local.fb-sandbox本地运行它。 Facebook应用程序设置将网站网址设置为http://local.fb-sandbox/。
当我转到http://local.fb-sandbox时,我被重定向到facebook登录页面,然后转到请求我的权限的页面,但应用程序然后进入如下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()并尝试使用和不使用它。 PHP cookie设置正常。
我在这里看到了很多关于这个重定向循环的类似问题,但没有一个建议的答案解决了它们,它们都很老了。这应该在localhost上工作吗? AM我在Facebook上的应用设置中错过了应用设置?
更新
所以看来如果你使用这里的代码:http://developers.facebook.com/docs/authentication/那么它就可以了。 github上的php-sdk示例完全忽略了这一点,并且不包括您需要检查“代码”是否已设置并生成您自己的CSRF令牌的事实。然后,您需要调用以获取访问令牌,然后才能调用Graph API。
此外,SDK的getLoginURL()方法返回一个似乎不起作用的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方法并使其正常工作(请记住我需要它在代理后面工作),那么你将获得赏金。
答案 0 :(得分:5)
许多服务器端Facebook SDK都没有根据Facebook在过去3或4个月内分享的文档和推荐做法来处理身份验证。您在PHP SDK如何使用(或不使用)代码参数时找到了一个很好的例子。还有其他一些例子,这些SDK直接读取Facebook的cookie,Facebook工程师告诉开发人员他们不应该这样做,因为cookie只是“实现细节”而不是Facebook之外的开发人员应该建立依赖关系。
我不确定您在工作代码示例中获得该代码的位置,但我找不到包含fbconnect=1
因此,根据Facebook推荐和文档,SDK没有实现身份验证,并且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.");
}
?>
答案 1 :(得分:1)
这有几个问题。
您的redirect_uri应该像http://local.fb-sandbox/。最后必须有一个尾部斜杠 - 在代码和developers.facebook.com中的facebook app设置中。
您必须在redirect_uri上使用uurlencode。
请勿在redirect_uri中使用$ _SERVER ['REQUEST_URI']。通过处理app_data或根据您的用户旅程添加它们,找到添加所需参数的方法。
作为开始替换这一行:
'redirect_uri' => urlencode('http://local.fb-sandbox/'),
并尝试稍后添加参数。