Facebook SDK returned an error: Cross-site request forgery validation failed. The “state” param from the URL and session do not match

后端 未结 25 864
南方客
南方客 2020-12-01 01:37

i\'m trying to get Facebook user id using the php sdk like this

$fb = new Facebook\\Facebook([
    \'app_id\' => \'11111111111\',
    \'app_secret\' =>         


        
相关标签:
25条回答
  • 2020-12-01 02:32

    With Symfony, it doesn't work because the way session are managed.

    To resolve the problem you can create a new handler wich work with symfony's session.

    FacebookDataHandlerSymfony.php :

    <?php
    
    use Facebook\PersistentData\PersistentDataInterface;
    use Symfony\Component\HttpFoundation\Session\Session;
    
    class FacebookDataHandlerSymfony implements PersistentDataInterface
    {
    
        private $session;
    
        public function __construct()
        {
            $this->session = new Session();
        }
    
        public function get($key)
        {
            return $this->session->get('FBRLH_' . $key);
        }
    
        public function set($key, $value)
        {
            $this->session->set('FBRLH_' . $key, $value);
        }
    
    }
    

    And when you create the FB Object, you have just to specifie the new class :

    $this->fb = new Facebook([
                'app_id' => '1234',
                'app_secret' => '1324',
                'default_graph_version' => 'v2.8',
                'persistent_data_handler' => new FacebookDataHandlerSymfony()
            ]);
    
    0 讨论(0)
  • 2020-12-01 02:35

    you could just do this set the session with the new state

    <?php
    if(isset($_GET['state'])) {
          if($_SESSION['FBRLH_' . 'state']) {
              $_SESSION['FBRLH_' . 'state'] = $_GET['state'];
          }
    }
    ?>
    
    0 讨论(0)
  • 2020-12-01 02:35

    For me the problem was different; (I was stupid) I had a popup window with Facebook login and again Facebook login buttons in Login/Signup page.

    • Whenever i click the Facebook button in the popup from other pages it worked fine.
    • But, when i click the Facebook button in the popup from Login/Signup page, it would not work.

    The reason was i had re-instantiated the Facebook and getRedirectLoginHelper objects. I had to comment out these statements in Login/Signup pages, as it was already available.

    $_SESSION['FBRLH_state']=$_GET['state'];
    

    is not the way to go. Although it worked.

    0 讨论(0)
  • 2020-12-01 02:36

    In my case i have checked error and found error which lead me to solution with executing code:

    date_default_timezone_set('Europe/Istanbul');
    

    before script. Worked like a charm. For your location check: timezones.europe.php

    0 讨论(0)
  • 2020-12-01 02:37

    Yii2 solution that works for me:

    use Facebook\PersistentData\PersistentDataInterface;
    use Yii;
    
    class PersistentDataHandler implements PersistentDataInterface
    {
        /**
         * @var string Prefix to use for session variables.
         */
        protected $sessionPrefix = 'FBRLH_';
    
        public function get($key)
        {
            return Yii::$app->session->get($this->sessionPrefix . $key);
        }
    
        public function set($key, $value)
        {
            Yii::$app->session->set($this->sessionPrefix . $key, $value);
        }
    }
    
    0 讨论(0)
  • 2020-12-01 02:38

    Finally, looking into FB code, I discovered that the problem

    Cross-site request forgery validation failed. Required param “state” missing

    and similars are caused by PHP variable $_SESSION['FBRLH_state'] that for some "strange" reason when FB call the login-callback file.

    To solve it I store this variable "FBRLH_state" AFTER the call of function $helper->getLoginUrl(...). Is very important to do only after the call of this function due to is inside this function when the variable $_SESSION['FBRLH_state'] is populated.

    Below an example of my code in the login.php:

    $uri=$helper->getLoginUrl($uri, $permissions);
    foreach ($_SESSION as $k=>$v) {                    
        if(strpos($k, "FBRLH_")!==FALSE) {
            if(!setcookie($k, $v)) {
                //what??
            } else {
                $_COOKIE[$k]=$v;
            }
        }
    }
    var_dump($_COOKIE);
    

    And in the login-callback.php before calling all FB code:

    foreach ($_COOKIE as $k=>$v) {
        if(strpos($k, "FBRLH_")!==FALSE) {
            $_SESSION[$k]=$v;
        }
    }
    

    Last, but not least, remember also to include code for PHP session so..

    if(!session_id()) {
        session_start();
    }
    ...
    ...
    ...
    ...
    <?php session_write_close() ?>
    

    I hope this response can help you to save 8-10 hours of work :) Bye, Alex.

    0 讨论(0)
提交回复
热议问题