【问题标题】:When using CodeIgniter + Facebook PHP SDK: getUser() always returns 0使用 CodeIgniter + Facebook PHP SDK 时:getUser() 总是返回 0
【发布时间】:2013-07-04 09:01:49
【问题描述】:

我正在尝试将 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 重定向到 login/facebook_login 方法的路由,该方法正在运行。

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

我目前的流程如下:

  1. 加载 hxxp://xxxxxxxx.com/(路由到登录控制器,加载 login_form 视图)
  2. 点击“用 Facebook 登录”链接
  3. Facebook 要求我登录(我这样做了)
  4. Facebook 要求我授予我的应用程序的权限(我这样做了)
  5. Facebook 将我重定向到 redirect_uri 参数中指定的 URL,该 URL 与应用设置页面上的相同

这就是一切都出错的地方。 $this->facebook->getUser() 方法总是返回 0,即使在身份验证之后也是如此。

我一直在搜索 Facebook 开发人员文档以及互联网上我能想到的其他任何地方,试图找到这个问题的答案。我遇到过许多类似的帖子,并尝试应用建议的解决方案,但无济于事。

我做错了什么?

【问题讨论】:

标签: php facebook codeigniter facebook-php-sdk


【解决方案1】:

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 设置中。

【讨论】:

    【解决方案2】:

    我设法解决了我的问题。 Qweick 和 Stéphane Bruckert 提出的问题有解决方案。问题出在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 调用现在返回有效数据。

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

    【讨论】:

    • 这并不能解决问题。
    • 或者您可以将'cookie' =&gt; true 添加到您的$facebook_config
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 2014-03-02
    • 2011-10-11
    • 2013-02-16
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多