Php 为什么我的测试应用程序处于无止境的重定向循环中?
我使用PHPSDK版本3.1.1对Graph API进行简单调用。我在本地运行它。facebook应用程序设置将网站URL设置为 我被重定向到facebook登录页面,然后转到请求我权限的页面,但应用程序随后进入URL之间的重定向循环,如:Php 为什么我的测试应用程序处于无止境的重定向循环中?,php,facebook,oauth,facebook-php-sdk,Php,Facebook,Oauth,Facebook Php Sdk,我使用PHPSDK版本3.1.1对Graph API进行简单调用。我在本地运行它。facebook应用程序设置将网站URL设置为 我被重定向到facebook登录页面,然后转到请求我权限的页面,但应用程序随后进入URL之间的重定向循环,如: http://local.fb-sandbox/?state=e9c091bb61afe08139af4e3b153a1e9e&code=AQBDJ4yMWVOIrukx6nRkxhNbnPH9nX6OvuqOWhVJEAgLkq6Lz27iq_-B
http://local.fb-sandbox/?state=e9c091bb61afe08139af4e3b153a1e9e&code=AQBDJ4yMWVOIrukx6nRkxhNbnPH9nX6OvuqOWhVJEAgLkq6Lz27iq_-B6AIAGQ_cOpBIZktCPLLs_G5Hpt8QO5PRhDUN8l-Yu3JuT0YTzwVQiAqBlgutgia60lRT-ZzE3IHguStHq4gtuPQYJh423TBer-mB8BsqERvNsoF1L4NNe90WAWU8--MFAU3Oc4eeXyI#_=_
及
我在脚本的顶部调用了session_start(),并尝试了使用和不使用它。PHP cookie正在设置为良好状态
关于这个重定向循环,我在这里看到了很多类似的问题,但是没有一个建议的答案解决了这个问题,而且它们都很旧。这应该在本地主机上工作吗?我是否在Facebook上的应用程序设置中缺少应用程序设置
更新
因此,如果您使用这里的代码:那么它就工作了。github上的PHPSDK示例完全忽略了这一点,并且不包括您需要检查是否设置了“代码”并生成自己的CSRF令牌这一事实。然后,在能够调用Graph API之前,需要进行调用以获取访问令牌
此外,SDK的getLoginURL()方法返回一个https://URL,该URL似乎不起作用。如果我设计了自己的URL,那么它就会工作
工作代码:
if(空($code)){
$_SESSION['state']=md5(uniqid(rand(),TRUE));
$login\u url\u params=数组(
“范围”=>“电子邮件、阅读流、发布流、用户照片、用户视频”,
“fbconnect”=>1,
'重定向\u uri'=>'http://local.fb-sandbox/',
'state'=>$\u会话['state']
);//通过sdk使用此数组不起作用
$dialog_url=”http://www.facebook.com/dialog/oauth?client_id="
.$app\u id.&redirect\u uri=“.urlencode($my\u url)。”&state=”
.$\u会话['state'];//此url有效
//变量转储($dialog\u url);回显“
”;
$login_url=$facebook->getLoginUrl();
//变量转储($login\u url);
标题(“位置:{$dialog_url}”);//有效
//标头(“位置:{$login_url}”);//不起作用
出口
}
if($\u请求['state']=$\u会话['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=数组(
“http'=>数组(
'代理'=>'tcp://xxxx0:80',
'request_fulluri'=>true,
),
);
$cxContext=stream\u context\u create($aContext);
$response=file\u get\u contents($token\u url,FALSE,$cxContext);
$params=null;
parse_str($response,$params);
$graph_url=”https://graph.facebook.com/me?access_token=“$params['access_token'];
$user=json_decode(文件获取内容($graph_url,FALSE,$cxContext));
//变量转储($user);退出;
}
//var_dump($user);出口
返回$app->render('test.html',数组('myvar',$user));
退出();
请注意,我正在使用代理,因此必须为文件\u get\u contents()调用设置上下文
如果有人可以将我的代码转换为使用适当的SDK方法并使其工作(请记住,我需要它在代理后工作),那么您将获得奖励。这有几个问题
'redirect_uri' => urlencode('http://local.fb-sandbox/'),
然后尝试添加参数。许多服务器端Facebook SDK都没有按照Facebook在过去3到4个月内共享的文档和推荐做法处理身份验证。PHP SDK如何使用(或不使用)代码参数就是一个很好的例子。还有其他一些例子,比如SDK直接读取Facebook cookies,Facebook工程师告诉开发者他们不应该这样做,因为cookies只是“一个实现细节”,而不是Facebook以外的开发者应该依赖的东西 我不确定您在工作代码示例中从何处获得该代码,但我找不到任何支持包含参数,例如
fbconnect=1
因此,鉴于SDK没有按照Facebook的建议和文档实施身份验证,并且Facebook在其文档中提供了完整的PHP实现,我建议您只使用Facebook提供的版本,复制并粘贴在此处,供您在本页面中参考:
登录成功后facebook返回代码,为什么要将其添加到登录url?这些建议没有解决问题。我已经删除了潜在的误导性评论。我已经试着换了那条线,但还是出了问题。我已经更新了上面的代码。还有其他想法吗?“你必须在重定向uri上使用uurlencode”有同样的问题;仅在用户首次验证应用程序时发生。Php给了我和你一样的错误;输出?@GilBirman:输出“0”既然您想知道,您是否尝试检查$\u REQUEST
变量是否包含state
参数?似乎$\u请求['state']
总是空的。您的完整htaccess
外观如何?状态和代码在$\u请求中。我已经添加了我的.htaccess。我想我已经排除了这个原因,谢谢帕特。您是否建议完全避免使用PHP-SDK?我主要使用.NET,因此我对PHP-SDK没有太多的第一手经验。我将告诉您,我使用C#SDK只是为了在使用自己的代码(即di)处理身份验证后进行api调用
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();
'redirect_uri' => urlencode('http://local.fb-sandbox/'),
<?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.");
}
?>