Я хотел реализовать новый facebook API v 4.0.0 в моем проекте laravel.

Установка всей необходимой информации и учетных данных для доступа к моему приложению, когда пора вызвать функцию для входа:

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

Это вызывает у меня исключение

FacebookSDKException «Сеанс не активен, не удалось сохранить состояние».

Итак, я копаюсь в SDK-классе facebook в этой строке, и есть проверка сеанса именно в этом:

 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, почему это произошло? таким образом я не могу использовать новый API facebook с laravel?

6
Fabrizio Fenoglio 6 Май 2014 в 22:04

6 ответов

Лучший ответ

Я решаю расширить этот класс и перезаписать следующие 2 метода, для которых требуются собственные сеансы.

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

    protected function loadState()
    {
        return $this->state =  Session::get('facebook.state');
    }
6
Fabrizio Fenoglio 7 Май 2014 в 10:42

Рассказываю, как я реализовал Facebook SDK V4 на Laravel 4.

Вот что я добавил в 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/"
    }
},

Добавлена ​​инициализация Facebook в мой index.php, например:

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

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

А для сеанса Laravel не использует $ _SESSION, поэтому вам вообще не нужно выполнять session_start. Чтобы вы могли использовать сеанс Laravel в Facebook PHP SDK V4, вам необходимо расширить класс 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 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;

    }

Не стесняйтесь комментировать или предлагать, чтобы я также мог улучшить свой код. Удачного кодирования.

13
kaixersoft 6 Июл 2014 в 09:28

Я использовал следующие шаги, используя Composer, и у меня возникла проблема «Сеанс не активен, не удалось сохранить состояние», поэтому 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>';
}
4
Ramratan Gupta 15 Май 2014 в 11:43

Чтобы решить проблему, вызовите функцию session_start php после инициализации FacebookRedirectLoginHelper примерно так:

session_start ( ) ;

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

$ loginUrl = $ helper-> getLoginUrl ();

0
theShadow89 7 Май 2014 в 10:00

Ответ kaixersoft действительно спас мой бекон некоторое время назад, и я заставил все работать, следуя его инструкциям, используя собственный класс LaravelFacebookRedirectLoginHelper. Но сегодня я пошел делать «композиторское обновление», и по какой-то причине все сломалось. Я изменил класс LaravelFacebookRedirectLoginHelper kaixersoft, чтобы он теперь работал, в частности метод 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;
   }


}
0
BakerStreetSystems 10 Мар 2015 в 04:06

Функция session_status доступна в версии (PHP> = 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.'
    );
}
-2
Abhay 8 Май 2014 в 05:37