我正在尝试将Facebook PHP SDK与CodeIgniter结合使用,以允许用户使用Facebook Connect登录我的网站。无论我尝试什么,getUser()总是返回0,即使在通过Facebook成功验证(显然)之后也是如此。
CodeIgniter版本:2.1.3
Facebook PHP SDK版本:3.2.2
我在application / config文件夹中创建了一个配置文件facebook.php,我正在通过CodeIgniter的$ this-> load-> library(...)方法加载Facebook PHP SDK。该库确实已加载,我可以成功调用许多get ...()方法,包括getAccessToken(),getAppId()和getAppSecret(),所有这些都返回它们的预期值。
以下是我的登录控制器的精简版本:(请注意,我还提供了另一种通过电子邮件登录的方法,因此整个过程中会出现CodeIgniter会话代码)
class Login extends CI_Controller {
public function __construct()
{
//Call parent constructor
parent::__construct();
//Magic sauce - not sure if this is required but a lot of other people
//are recommending it to be included (happy to remove it if necessary)
parse_str($_SERVER['QUERY_STRING'], $_REQUEST);
//Load facebook library
$facebook_config = $this->load->config('facebook');
$this->load->library('facebook', $facebook_config);
}
public function index()
{
//Check if user is logged in
$user_id = $this->session->userdata('user_id');
$is_logged_in = $this->session->userdata('is_logged_in');
if(($is_logged_in) && ($user_id != 0)) {
//Logged in - redirect to game
redirect('game');
} else {
//Not logged in
//Get facebook login url
$facebook_data = array(
'redirect_uri' => 'hxxp://xxxxxxxx.com/facebook_login/',
'scope' => 'email'
);
$data['facebook_login_url'] = $this->facebook->getLoginUrl($facebook_data);
//Redirect to login form
$this->load->view('login/login_form', $data);
}
}
public function facebook_login()
{
//Always returns 0!! Even after authenticating via facebook!
$facebook_user_id = $this->facebook->getUser();
if ($facebook_user_id) {
try {
$user_profile = $this->facebook->api('/me');
print_r($user_profile);
} catch (FacebookApiException $e) {
echo $e->getMessage();
}
} else {
echo "Could not log in with Facebook";
}
}
}
精简视图(login_form.php)如下:
<html>
<head>
<title>Facebook Connect Test</title>
</head>
<body>
<a href='<? echo $facebook_login_url; ?>'>Login with Facebook</a>
</body>
</html>
我有一条路线将hxxp://xxxxxxxx.com/facebook_login重定向到登录/ facebook_login方法,该方法正在运行。
我在实时开发服务器上运行此代码。
我目前的流程如下:
这就是出错的地方。即使在身份验证之后,$ this-&gt; facebook-&gt; getUser()方法也会返回0。
我一直在搜索Facebook开发者文档和互联网上的其他任何地方,我可以想到试图找到答案。我遇到过很多与此相似的帖子,并尝试应用建议的解决方案,但无济于事。
我做错了什么?
答案 0 :(得分:3)
base_facebook.php中的getCode()方法使用$ _REQUEST全局来存储数据。 PHP 5.3.0和更高版本使用php.ini中的“request_order”参数,默认情况下$ _REQUEST不包含Cookie变量。
每个php.net(http://php.net/manual/en/ini.core.php#ini.request-order):
“该指令描述了PHP将GET,POST和Cookie变量注册到_REQUEST数组中的顺序。注册从左到右完成,较新的值覆盖较旧的值。
如果未设置此指令,则variables_order用于$ _REQUEST内容。
请注意,出于安全考虑,默认分发php.ini文件不包含Cookie的“C”。“
所以看起来你的选择是像上面的Max Power那样修改getCode()方法,或者更新你的php.ini并将“C”值添加到request_order设置。
答案 1 :(得分:2)
我设法解决了我的问题。 Qweick和StéphaneBruckert所提出的问题有解决方案。问题在于base_facebook.php文件的getCode()函数。
需要修改getCode()函数。我使用的修改如下所列。
现有的非工作代码:
protected function getCode() {
if (isset($_REQUEST['code'])) {
if ($this->state !== null &&
isset($_REQUEST['state']) &&
$this->state === $_REQUEST['state']) {
// CSRF state has done its job, so clear it
$this->state = null;
$this->clearPersistentData('state');
return $_REQUEST['code'];
} else {
self::errorLog('CSRF state token does not match one provided.');
return false;
}
}
return false;
}
修改后的工作代码:
protected function getCode() {
$server_info = array_merge($_GET, $_POST, $_COOKIE);
if (isset($server_info['code'])) {
if ($this->state !== null &&
isset($server_info['state']) &&
$this->state === $server_info['state']) {
// CSRF state has done its job, so clear it
$this->state = null;
$this->clearPersistentData('state');
return $server_info['code'];
} else {
self::errorLog('CSRF state token does not match one provided.');
return false;
}
}
return false;
}
getUser()调用现在返回有效的用户ID,Facebook API调用现在返回有效数据。
感谢所有帮助我指明正确方向的人!