【问题标题】:Facebook PHP SDK exception errorFacebook PHP SDK 异常错误
【发布时间】:2014-06-12 21:19:47
【问题描述】:

我从 FB 的 PHP SDK 收到一条有趣的 SDK 异常消息。我完全按照 FB 文档的要求设置了我的代码..?

调试错误消息:

[12-Jun-2014 21:08:12 UTC] PHP Fatal error:  Uncaught exception 'Facebook\FacebookSDKException' with message 'Session not active, could not store state.' in C:\WebRoot\Website\root\inc\Facebook\FacebookRedirectLoginHelper.php:188
Stack trace:
#0 C:\WebRoot\Website\root\inc\Facebook\FacebookRedirectLoginHelper.php(94):Facebook\FacebookRedirectLoginHelper->storeState('**********...')
#1 C:\WebRoot\Website\root\login\index.php(87): Facebook\FacebookRedirectLoginHelper->getLoginUrl()
#2 {main}
   thrown in C:\WebRoot\Website\root\inc\Facebook\FacebookRedirectLoginHelper.php on line 188

Facebook.php:

<?php
require_once("../inc/config.php");
require_once(ROOT_PATH . 'inc/Facebook/FacebookSession.php' );
require_once(ROOT_PATH . 'inc/Facebook/FacebookRedirectLoginHelper.php' );
require_once(ROOT_PATH . 'inc/Facebook/FacebookRequest.php' );
require_once(ROOT_PATH . 'inc/Facebook/FacebookResponse.php' );
require_once(ROOT_PATH . 'inc/Facebook/FacebookSDKException.php' );
require_once(ROOT_PATH . 'inc/Facebook/FacebookRequestException.php' );
require_once(ROOT_PATH . 'inc/Facebook/FacebookAuthorizationException.php' );
require_once(ROOT_PATH . 'inc/Facebook/GraphObject.php' );
require_once(ROOT_PATH . 'inc/Facebook/HttpClients/FacebookCurl.php' );
require_once(ROOT_PATH . 'inc/Facebook/HttpClients/FacebookHttpable.php' );
require_once(ROOT_PATH . 'inc/Facebook/HttpClients/FacebookCurlHttpClient.php' );

use Facebook\FacebookSession;

// init app with app id (APPID) and secret (SECRET)
FacebookSession::setDefaultApplication("**********","*******************");

主登录页面:

<?php
require_once("../inc/config.php");
require_once(ROOT_PATH . 'inc/Facebook/Facebook.php' );
require_once(ROOT_PATH . "inc/LoginHelper.php");

use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
use Facebook\FacebookResponse;
use Facebook\FacebookSDKException;
use Facebook\FacebookRequestException;
use Facebook\FacebookAuthorizationException;
use Facebook\GraphObject;
use Facebook\HttpClients\FacebookCurl;
use Facebook\HttpClients\FacebookHttpable;
use Facebook\HttpClients\FacebookCurlHttpClient;

session_start();

// login helper with redirect_uri
$helper = new FacebookRedirectLoginHelper( '***********' );

主登录页面上的链接:

<a href="<?php echo $helper->getLoginUrl();?>"><img src="<?php echo BASE_URL; ?>img/facebook-login-button.png" class="fb-login"></a>

重定向网址页面:

<?php
require_once("../inc/config.php");
require_once(ROOT_PATH . 'inc/Facebook/Facebook.php' );

use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
use Facebook\FacebookResponse;
use Facebook\FacebookSDKException;
use Facebook\FacebookRequestException;
use Facebook\FacebookAuthorizationException;
use Facebook\GraphObject;
use Facebook\HttpClients\FacebookCurl;
use Facebook\HttpClients\FacebookHttpable;
use Facebook\HttpClients\FacebookCurlHttpClient;

session_start();

//get user login token from FB
$helper = new FacebookRedirectLoginHelper('*******');
try {
   $session = $helper->getSessionFromRedirect();
} catch(FacebookRequestException $ex) {
     echo $ex;
  // When Facebook returns an error
} catch(Exception $ex) {
    echo $ex;
  // When validation fails or other local issues
}
if ($session) {
    $FacebookAccessToken = $session->getToken();
   // Logged in
}

【问题讨论】:

  • session_start();放在每个文件的顶部...

标签: php facebook


【解决方案1】:

session_start(); 放在文件的顶部

【讨论】:

    【解决方案2】:

    为了扩展 Chancho 的答案,SDK 会在尝试向其存储任何数据之前检查会话是否处于活动状态。有 3 种解决方法。

    启动原生 PHP 会话

    如果您只是使用 PHP 的本机会话,Chancho 的回答就足够了。在发送任何输出之前,您必须确保 session_start(); 位于脚本的最顶部。

    覆盖会话处理

    如果您使用像 Codeigniter、Yii、CakePHP、Laravel 等 Web 框架,它们通常有自己的方式来存储会话。要覆盖默认会话存储,您需要编写自己的类来扩展 \Facebook\FacebookRedirectLoginHelper 类。然后你需要覆盖storeState()loadState() 方法。这是整个 SDK 中仅有的两个与 $_SESSION 变量接口的方法。

    您可以在 SDK 的 GitHub 问题中看到 laravel implementation example。这是 laravel 的实现:

    class MyFacebookRedirectLoginHelper extends \Facebook\FacebookRedirectLoginHelper
    {
      protected function storeState($state)
      {
        Session::put('state', $state);
      }
    
      protected function loadState()
      {
        return $this->state = Session::get('state');
      }
    }
    

    完全禁用会话检查

    如果您尝试在命令行等无状态环境中使用 SDK,则启动会话或覆盖会话数据的存储方式是没有意义的。您可以简单地使用FacebookRedirectLoginHelper::disableSessionStatusCheck() 禁用检查。

    要禁用会话检查,只需运行这个。

    $helper = new FacebookRedirectLoginHelper('*******');
    
    $helper->disableSessionStatusCheck();
    
    $session = $helper->getSessionFromRedirect();
    
    // . . . 
    

    希望对你有帮助!

    【讨论】:

    • 很好的解决方案!我正在使用 Laravel 4
    • 这似乎不再适用于较新的 SDK。有什么想法吗?
    【解决方案3】:

    用于使用 CakePHP v3.1.6 + Facebook SDK v4.1。

    在较新的 SDK 中,\Facebook\FacebookRedirectLoginHelper 类已更改为使用 \Facebook\FacebookSessionPersistentDataHandler 类来处理会话“状态”。将 $this->request->session()->start() 放入 AppController 初始化将解决使用带有 AuthComponent 的 Facebook SDK 的问题。

    public function initialize() {
        parent::initialize();
        $this->request->session()->start();
    
        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');
    
        $this->loadComponent('Auth', [
            'authenticate' => [
                'Form' => [
                    'fields' => ['username' => 'email', 'password' => 'password']
                ]
            ],
            'loginAction' => ['controller' => 'Users', 'action' => 'login']
        ]);
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-31
      • 2011-11-15
      • 2012-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多