新的Facebook SDK 4在laravel中抛出关于PHP_SESSION_ACTIVE的异常

时间:2014-05-06 18:04:02

标签: facebook laravel-4 facebook-php-sdk

我想在我的项目laravel上实现新的facebook API v 4.0.0。

设置所有必要的信息和凭据以访问我的应用,何时是时候调用登录功能:

$helper = new FacebookRedirectLoginHelper('http://mywebsite.dev');
$loginUrl = $helper->getLoginUrl();

它给我一个例外

  

FacebookSDKException'会话未激活,无法存储状态。'

所以我在那条线上深入了解facebook的SDK类,并且正确地检查了这个会话:

 if (session_status() !== PHP_SESSION_ACTIVE) {
      throw new FacebookSDKException(
        'Session not active, could not store state.'
      );
    }

然后我不知道为什么会发生这种情况所以我试着在干净的路线上进行相同的检查并看到结果

Route::get('test',function() {

   if (session_status() !== PHP_SESSION_ACTIVE)
    {
        return "is not active";
    }

    return "is active";

});

它返回is not active为什么会发生这种情况?这样我就不能在laravel中使用新的facebook API了?

6 个答案:

答案 0 :(得分:13)

分享我在Laravel 4上实施Facebook SDK V4的方式。

这是我在默认的composer.json上添加的内容

"autoload": {
    "classmap": [
        "app/commands",
        "app/controllers",
        "app/models",
        "app/database/migrations",
        "app/database/seeds",
        "app/tests/TestCase.php"
    ],
    "psr-4" : {
        "Facebook\\":"vendor/facebook/php-sdk-v4/src/Facebook/"
    }
},

在我的index.php上添加了Facebook初始化,如下所示:

/*
|--------------------------------------------------------------------------
| Initialized Facebook PHP SDK V4
|--------------------------------------------------------------------------
|
*/

//Initialize
use Facebook\FacebookSession;
FacebookSession::setDefaultApplication(Config::get('facebook.AppId'),Config::get('facebook.AppSecret'));

对于Session,Laravel不使用$ _SESSION,因此您根本不需要执行session_start。为了能够在Facebook PHP SDK V4上使用Laravel会话,您需要扩展Facebook的 FacebookRedirectLoginHelper 类。 以下是如何子类 FacebookRedirectLoginHelper 并覆盖会话处理。

class LaravelFacebookRedirectLoginHelper extends \Facebook\FacebookRedirectLoginHelper
{

  protected function storeState($state)
  {
    Session::put('state', $state);
  }

  protected function loadState()
  {
    $this->state = Session::get('state');
    return $this->state;
  }


  protected function isValidRedirect()
  {

    return $this->getCode() && Input::has('state')
        && Input::get('state') == $this->state;

  }



  protected function getCode()
  {
    return Input::has('code') ? Input::get('code') : null;
  }


  //Fix for state value from Auth redirect not equal to session stored state value
  //Get FacebookSession via User access token from code
  public function getAccessTokenDetails($app_id,$app_secret,$redirect_url,$code)
  {

        $token_url = "https://graph.facebook.com/oauth/access_token?"
          . "client_id=" . $app_id . "&redirect_uri=" . $redirect_url
          . "&client_secret=" . $app_secret . "&code=" . $code;

        $response = file_get_contents($token_url);
        $params = null;
        parse_str($response, $params);

        return $params;
   }


}

还有一步,您需要执行composer命令来重新生成自动加载文件:

composer dump-autoload -o

好的,如果一切正常,您现在可以开始使用SDK了,这是一个示例

以下是我的一个项目类的摘录:

namespace Fb\Insights;

//Facebook Classes
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\FacebookSDKException;


//Our Facebook Controller
use FbController;

class PagePosts extends \Facebook\GraphObject {

    /*
        Get Page Posts Impression
        https://developers.facebook.com/docs/graph-api/reference/v2.0/insights#post_impressions     


    */
    public static function getPagePostsImpressions($postid = null) {

        $fbctrl = new FbController();

        $metricNames = array(
            'post_impressions',
            'post_impressions_unique',
            'post_impressions_paid',
            'post_impressions_paid_unique',
            'post_impressions_fan',
            'post_impressions_fan_unique',
            'post_impressions_fan_paid',
            'post_impressions_fan_paid_unique',
            'post_impressions_organic',
            'post_impressions_organic_unique',
            'post_impressions_viral',
            'post_impressions_viral_unique',
            'post_impressions_by_story_type',
            'post_impressions_by_story_type_unique',
            'post_impressions_by_paid_non_paid',
            'post_impressions_by_paid_non_paid_unique'
        );

        $postsInsights = array();       
        $batch = array();
        $limit = $fbctrl->FacebookGraphDateLimit();     


        //craft our batch API call
        for($i=0; $i<count($metricNames); $i++) {       
            $batch[] = json_encode(array('method' => 'GET','relative_url' => $postid . '/insights/' . $metricNames[$i] . '?since=' . $limit['since'] . '&until=' . $limit['until'] ));
        }
        $params = array( 'batch'    => '[' . implode(',',$batch ) . ']' );      

        $session = new FacebookSession($fbctrl->userAccessToken);

        try {

            $res = (new FacebookRequest($session,'POST','/',$params))
                ->execute()
                ->getGraphObject();

        } catch(FacebookRequestException $ex) {
            //log this error
            echo $ex->getMessage();
        } catch(\Exception $ex) {
            //log this error
            echo $ex->getMessage();
        }

        //Collect data
        for($i=0; $i<count($batch); $i++) {

            $resdata = json_decode(json_encode($res->asArray()[$i]),true);

            $fbctrl->batchErrorDataChecker($resdata,$postsInsights,$metricNames[$i]);

        }

        return $postsInsights;

    }

免费评论或建议,以便我也可以改进我的代码。 快乐的编码。

答案 1 :(得分:6)

我解决了扩展该类并覆盖以下需要本机会话的两种方法的问题。

    protected function storeState($state)
    {
        Session::put('facebook.state', $state);
    }

    protected function loadState()
    {
        return $this->state =  Session::get('facebook.state');
    }

答案 2 :(得分:4)

我使用了使用Composer的后续步骤并遇到问题&#34;会话未激活,无法存储状态&#34;所以session_start()解决了我的问题。

require_once './vendor/autoload.php';

use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;

session_start();
FacebookSession::setDefaultApplication('apid', 'appscret');
$helper = new FacebookRedirectLoginHelper("callbackurl", $apiVersion = NULL);
try {
    $session = $helper->getSessionFromRedirect();
} catch (FacebookRequestException $ex) {
    // When Facebook returns an error
} catch (\Exception $ex) {
    // When validation fails or other local issues
}
if (isset($session)) {

    $request = new FacebookRequest($session, 'GET', '/me');
    $response = $request->execute();
    $graphObject = $response->getGraphObject();
    var_dump($graphObject);
} else {
    echo '<a href="' . $helper->getLoginUrl() . '">Login with Facebook</a>';
}

答案 3 :(得分:0)

解决问题调用session_start php函数后,将FacebookRedirectLoginHelper这样的事情搞砸:

  

在session_start();

     

$ helper = new FacebookRedirectLoginHelper(&#39; http://mywebsite.dev&#39;);

     

$ loginUrl = $ helper-&gt; getLoginUrl();

答案 4 :(得分:0)

kaixersoft的答案在不久前真的保存了我的培根,我通过使用自定义LaravelFacebookRedirectLoginHelper类按照他的指示完成了所有工作。但今天我去做了一个作曲家更新&#39;由于某种原因,它打破了一切。我已经修改了kaixersoft的LaravelFacebookRedirectLoginHelper类,以便它现在可以正常工作,特别是isValidRedirect方法。这是更新的课程:

class LaravelFacebookRedirectLoginHelper extends \Facebook\FacebookRedirectLoginHelper
{

  protected function storeState($state)
  {
    Session::put('state', $state);
  }

  protected function loadState()
  {
    $this->state = Session::get('state');
    return $this->state;
  }


  protected function isValidRedirect()
  {
    $savedState = $this->loadState();
    if (!$this->getCode() || !isset($_GET['state'])) {
      return false;
    }
    $givenState = $_GET['state'];
    $savedLen = mb_strlen($savedState);
    $givenLen = mb_strlen($givenState);
    if ($savedLen !== $givenLen) {
      return false;
    }
    $result = 0;
    for ($i = 0; $i < $savedLen; $i++) {
      $result |= ord($savedState[$i]) ^ ord($givenState[$i]);
    }
    return $result === 0;
  }



  protected function getCode()
  {
    return Input::has('code') ? Input::get('code') : null;
  }


  //Fix for state value from Auth redirect not equal to session stored state value
  //Get FacebookSession via User access token from code
  public function getAccessTokenDetails($app_id,$app_secret,$redirect_url,$code)
  {

        $token_url = "https://graph.facebook.com/oauth/access_token?"
          . "client_id=" . $app_id . "&redirect_uri=" . $redirect_url
          . "&client_secret=" . $app_secret . "&code=" . $code;

        $response = file_get_contents($token_url);
        $params = null;
        parse_str($response, $params);

        return $params;
   }


}

答案 5 :(得分:-2)

session_status函数在(PHP&gt; = 5.4.0)版本上可用。因此,如果您使用的是旧版本的PHP,请更新它或只是

 // change this 

 if (session_status() !== PHP_SESSION_ACTIVE) {

      throw new FacebookSDKException(
        'Session not active, could not store state.'
      );
    }



//into this

if(session_id() === "") {

    throw new FacebookSDKException(
        'Session not active, could not load state.'
    );
}
相关问题