New Facebook SDK 4 throws exception from PHP_SESSION_ACTIVE in laravel

I wanted to implement the new facebook v 4.0.0 API on my laravel project.

Setting all the necessary information and credentials to access my application when it is time to call the function to enter:

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

This eliminates the exception.

FacebookSDKException 'Session is inactive, failed to save state.

So, I delve into the facebook SDK class on this line, and there is a check about the session of exactly this:

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

Then I did not know why this happened, so I tried to put the same check on a clean route and see the result

 Route::get('test',function() { if (session_status() !== PHP_SESSION_ACTIVE) { return "is not active"; } return "is active"; }); 

And this returns is not active , why is this happening? so i cant use the new facebook api with laravel?

+6
source share
6 answers

I allow to extend this class and overwrite the following 2 methods that require their own sessions.

  protected function storeState($state) { Session::put('facebook.state', $state); } protected function loadState() { return $this->state = Session::get('facebook.state'); } 
+6
source

Sharing how I implemented the Facebook SDK V4 on Laravel 4.

Here is what I added by default 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/" } }, 

Added Facebook initialization function on my index.php, for example:

 /* |-------------------------------------------------------------------------- | Initialized Facebook PHP SDK V4 |-------------------------------------------------------------------------- | */ //Initialize use Facebook\FacebookSession; FacebookSession::setDefaultApplication(Config::get('facebook.AppId'),Config::get('facebook.AppSecret')); 

And for a session, Laravel does not use $ _SESSION, so you don’t have to do session_start at all. In order for you to use the Laravel session on the Facebook PHP SDK V4, you need to extend the Facebook class FacebookRedirectLoginHelper. Here's how to subclass FacebookRedirectLoginHelper and overwrite session processing.

 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; } } 

And one more step, you need to execute the composer command to regenerate startup files:

 composer dump-autoload -o 

Well, if everything goes right, now you are ready to start using the SDK, here is a sample

Here is an excerpt from one of my project classes:

 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; } 

Feel free to comment or suggest so that I can improve my code. Happy coding.

+13
source

I used the following steps using Composer and had the problem "Session is inactive, could not save state", so session_start () fixed my problem.

 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>'; } 
+4
source

To solve the session_start problem call the php function after initializing FacebookRedirectLoginHelper somthing like this:

session_start ();

$ helper = new FacebookRedirectLoginHelper (' http://mywebsite.dev ');

$ loginUrl = $ helper-> getLoginUrl ();

0
source

Kaixersoft's answer really saved my bacon some time ago, and I got everything to work by following its instructions using its own LaravelFacebookRedirectLoginHelper class. But today I went to do a “composer update”, and for some reason he broke everything. I changed the kaixersoft LaravelFacebookRedirectLoginHelper class to work now, in particular the isValidRedirect method. Here is the updated class:

 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; } } 
0
source

The session_status function is available in version (PHP> = 5.4.0). Therefore, if you are using an older version of PHP, then upgrade it or just

  // 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.' ); } 
-2
source

All Articles