使用CodeIgniter + Facebook PHP SDK时:getUser()始终返回0

时间:2013-07-06 12:03:42

标签: php facebook codeigniter facebook-php-sdk

我正在尝试将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方法,该方法正在运行。

我在实时开发服务器上运行此代码。

我目前的流程如下:

  1. 加载hxxp://xxxxxxxx.com/(路由到登录控制器,加载login_form视图)
  2. 点击“使用Facebook登录”链接
  3. Facebook要求我登录(我这样做)
  4. Facebook要求我授权我的应用程序(我这样做)
  5. Facebook将我重定向到redirect_uri参数中指定的网址,该网址与应用设置页面上的网址相同
  6. 这就是出错的地方。即使在身份验证之后,$ this-&gt; facebook-&gt; getUser()方法也会返回0。

    我一直在搜索Facebook开发者文档和互联网上的其他任何地方,我可以想到试图找到答案。我遇到过很多与此相似的帖子,并尝试应用建议的解决方案,但无济于事。

    我做错了什么?

2 个答案:

答案 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调用现在返回有效数据。

感谢所有帮助我指明正确方向的人!