Facebook PHP SDK 5 :: API 2.4 :: Convalida falsificazione richiesta cross-site non rioutput. Param mancante "stato" param

Ho fatto uno script PHP molto semplice, solo per provare ad accedere tramite Facebook e get un accesso. Ma quando provo il codice seguente, ottengo un'exception dall'SDK: "Convalida della falsificazione della richiesta tra i siti non rioutput. Param mancante "stato" param. ».

Ecco il mio codice:

require_once __DIR__ . '/facebook-sdk-v5/autoload.php'; session_start(); $fb = new Facebook\Facebook([ 'app_id' => '{my-own-app-id}', 'app_secret' => '{my-own-app-secret}' ]); // Check to see if we already have an accessToken ? if (isset($_SESSION['facebook_access_token'] )) { $accessToken = $_SESSION['facebook_access_token']; echo "Horray we have our accessToken:$accessToken<br />\n"; } else { // We don't have the accessToken // But are we in the process of getting it ? if (isset($_REQUEST['code'])) { $helper = $fb->getRedirectLoginHelper(); try { $accessToken = $helper->getAccessToken(); } catch(Facebook\Exceptions\FacebookResponseException $e) { // When Graph returns an error echo 'Graph returned an error: ' . $e->getMessage(); exit; } catch(Facebook\Exceptions\FacebookSDKException $e) { // When validation fails or other local issues echo 'Facebook SDK returned an error: ' . $e->getMessage(); exit; } if (isset($accessToken)) { // Logged in! $_SESSION['facebook_access_token'] = (string) $accessToken; // Now you can redirect to another page and use the // access token from $_SESSION['facebook_access_token'] echo "Finally logged in! Token:$accessToken"; } } else { // Well looks like we are a fresh dude, login to Facebook! $helper = $fb->getRedirectLoginHelper(); $permissions = ['email', 'user_likes']; // optional $loginUrl = $helper->getLoginUrl('http://mywebsite.com/myapp/index.php', $permissions); echo '<a href="' . $loginUrl . '">Log in with Facebook!</a>'; } } exit; 

Ho dovuto aggiungere queste righe in alcuni server:

 $helper = $fb->getRedirectLoginHelper(); if (isset($_GET['state'])) { $helper->getPersistentDataHandler()->set('state', $_GET['state']); } 

Ottengo questo errore casualmente, a seconda della configuration del server.

Se stai utilizzando una versione "www" del tuo sito per generare il link di accesso e sei reindirizzato alla versione non www, ti imbatterai in problemi con la tua session. Quindi assicurati di accedere alla versione www del tuo sito e quindi definire l'url di richiamata alla stessa versione di www. Inoltre, puoi definire reindirizzamenti permanenti nella configuration del tuo server per assicurarti che chiunque acceda al tuo sito dalla versione non www venga reindirizzato alla versione www o viceversa.

session_start () all'inizio di entrambi gli script. Ho ottenuto la soluzione da qui: https://github.com/facebook/facebook-php-sdk-v4/issues/473

si riceve questo errore se il nome host di origine è diverso dal nome host di destinazione una volta autenticato.

 $loginUrl = $helper->getLoginUrl('http://mywebsite.com/myapp/index.php', $permissions); 

con questa affermazione, se il visitatore sul tuo sito web utilizza http://www.mywebsite.com/ l'errore di cross-site verrà generato.

È necessario assicurarsi che l'origine e il nome host di destinazione siano esattamente gli stessi, incluso l'eventuale prefisso www.

Versione fissa:

 $loginUrl = $helper->getLoginUrl('http://'.$_SERVER['SERVER_NAME'].'/myapp/index.php', $permissions); 

Ho incontrato un problema simile e ho trovato la soluzione di Nanang Koesharwanto. È più simile a quirk che modificare i file sorgente nella directory del venditore è una pessima idea. Quindi ecco il trucco.

 public function callback(Request $request) { $this->helper->getPersistentDataHandler()->set('state', $request->state); return $this->helper->getAccessToken(); } 

Se fallisce, use Session; nel tuo controller.

Ho anche incontrato lo stesso problema e dopo aver fatto delle ricerche su StackOverflow per mettere la linea

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

sopra ha risolto il mio problema

 $helper = $fb->getRedirectLoginHelper(); 

L'impostazione di [PersistentDataHandler] in modo esplicito prima di get i token garantirà che la richiesta sarà un successo. Di seguito viene mostrato come recuperare $ _GET ['state'] e semplicemente inserirlo nel "da utilizzare [helper]" su Symfony 2.x | 3.x

Ho avuto lo stesso identico problema dell'OP e questo ha risolto il mio problema.

 //create your new facebook sdk instance $this->fb = new Facebook([ 'app_id' => $facebookAppId, 'app_secret' =>$facebookAppSecret, 'default_graph_version' =>$facebookDefaultGraphVersion ]); //retrieve the helper $this->helper = $this->fb->getRedirectLoginHelper(); //below is the money shot //setting this explicitly before you get your tokens will guarantee that the request will be a success. It Fetches $_GET['state'] & simply injects it into the "to be used [helper]" $this->helper->getPersistentDataHandler()->set('state', $request->query->get('state')); 

Per me il problema si risolve ora solo avviando la session aggiungendo questo:

 session_start(); 

all'inizio di entrambi i file (il primo file che genera l'url di Facebook e il file di callback: login.php e fb-callback.php ( https://developers.facebook.com/docs/php/howto/example_facebook_login )).

Ho anche dovuto aggiungere questo:

 $config['app_id'] = 'myapp_id'; 

nella parte superiore per evitare un altro errore non correlato.

Come ho risposto qui: Facebook SDK ha restituito un errore: validation della falsificazione della richiesta tra i vari siti non rioutput. Il parametro "stato" dall'URL e dalla session non corrisponde

è necessario assicurarsi che la function di session PHP nativa sia impostata correttamente.

Laravel 5.2

Ho anche questo errore "Convalida falso richiesta cross-site fallita. Param richiesto" stato "mancante".

e dopo aver letto questo per ore. Ho provato a cambiare lo script del fornitore.

nel vendor\facebook\php-sdk-v4\src\Facebook\Helpers\FacebookRedirectLoginHelper.php sulla row 123, cambio questo script:

 private function makeUrl($redirectUrl, arrays $scope, arrays $params = [], $separator = '&') { $state = $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); $this->persistentDataHandler->set('state', $state); return $this->oAuth2Client->getAuthorizationUrl($redirectUrl, $state, $scope, $params, $separator); } 

in (aggiungo Session::put('state', $state); )

 private function makeUrl($redirectUrl, arrays $scope, arrays $params = [], $separator = '&') { $state = $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); $this->persistentDataHandler->set('state', $state); Session::put('state', $state); return $this->oAuth2Client->getAuthorizationUrl($redirectUrl, $state, $scope, $params, $separator); } 

e sulla linea 234, cambio questo script:

 protected function validateCsrf() { $state = $this->getState(); $savedState = $this->persistentDataHandler->get('state'); if (!$state || !$savedState) { throw new FacebookSDKException('Cross-site request forgery validation failed. Required param "state" missing.'); } $savedLen = strlen($savedState); $givenLen = strlen($state); if ($savedLen !== $givenLen) { throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); } $result = 0; for ($i = 0; $i < $savedLen; $i++) { $result |= ord($state[$i]) ^ ord($savedState[$i]); } if ($result !== 0) { throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); } } 

in (Ho aggiunto $this->persistentDataHandler->set('state', Session::get('state')); )

 protected function validateCsrf() { $state = $this->getState(); $this->persistentDataHandler->set('state', Session::get('state')); $savedState = $this->persistentDataHandler->get('state'); if (!$state || !$savedState) { throw new FacebookSDKException('Cross-site request forgery validation failed. Required param "state" missing.'); } $savedLen = strlen($savedState); $givenLen = strlen($state); if ($savedLen !== $givenLen) { throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); } $result = 0; for ($i = 0; $i < $savedLen; $i++) { $result |= ord($state[$i]) ^ ord($savedState[$i]); } if ($result !== 0) { throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); } } 

questo è tutto ciò che ho fatto. e l'errore è andato.

Questo è un problema comune che molte persone affrontano in FB Api. questo è solo un problema di SESSIONE. Per risolvere questo problema aggiungi del codice simile.

Sullo script di callback di solito fb-callback.php aggiungi "session_start ();" appena prima di includere il file autoload di Facebook. e quindi "$ _SESSION ['FBRLH_state'] = $ _ OTTIENI ['stato'];" dopo "$ helper = $ fb-> getRedirectLoginHelper ();" linea.

Esempio :

 <?php session_start(); /*Add session start*/ include 'vendor/autoload.php'; include 'config.php'; /*Facebook Config*/ $helper = $fb->getRedirectLoginHelper(); $_SESSION['FBRLH_state']=$_GET['state']; /*Add This*/ try { $accessToken = $helper->getAccessToken(); } ?> 

Il vero problema qui era la codifica del mio file PHP. Ho usato UTF8, ma avrebbe dovuto essere UTF8 senza BOM.

L'effetto collaterale della codifica errata era che la mia SESSIONE non funzionava correttamente e quindi l'SDK non era in grado di recuperare le informazioni necessarie per funzionare correttamente.

Una segnalazione degli errori correttamente configurata avrebbe detto che c'era un problema in modo diretto.

Penso che possiamo riempire questo bug nella categoria "noob". Ma comunque, penso che possa essere utile ad altri noob come me.

Infine, esaminando il codice FB, ho scoperto che il problema "Convalida falsificazione richiesta cross-site fallita. Param richiesto" stato "mancante" e similari sono causati dalla variabile PHP $ _SESSION ['FBRLH_state'] che per qualche motivo "strano" quando FB chiama il file di callback di accesso.

Per risolverlo, memorizzo questa variabile "FBRLH_state" DOPO il richiamo della function $ helper-> getLoginUrl (…). È molto importnte fare solo dopo che la chiamata di questa function è all'interno di questa function quando la variabile $ _SESSION ['FBRLH_state'] è popolata.

Di seguito un esempio del mio codice nel 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); 

E nel login-callback.php prima di call tutto il codice FB:

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

Ultimo, ma non less importnte, ricordati di includere anche il codice per la session PHP quindi ..

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

Spero che questa risposta possa aiutarti a risparmiare 8-10 ore di lavoro 🙂 Ciao, Alex.

devi assicurarti che la session inizi prima dell'esecuzione dello script. ma ancora una volta lancerà un 443: Network is unreachable se si avvia nuovamente una session sullo stesso script. Spero che questo aiuti qualcuno.

Ho appena usato if (session_status() == PHP_SESSION_NONE){ session_start(); } if (session_status() == PHP_SESSION_NONE){ session_start(); }

A quelli di voi che usenetworking cakephp 3.x e hanno questo problema e non avete idea di come risolverlo. Aggiungi session_start (); all'inizio del tuo metodo auth e callback.

 public function Facebookauth() { session_start(); $fb = new Facebook([ 'app_id' => '{app_id}', 'app_secret' => '{app_secret}', 'default_graph_version' => 'v2.6', .......... ]); you can still use $session = $this->request->session(); 

Per me questo stava accadendo a causa di 'persistent_data_handler' . Aggiungendo questo nella configuration di Facebook, sono riuscito a farlo funzionare.

 session_start(); $fb = new Facebook\Facebook([ 'app_id' => '6XXXXXXXXX', 'app_secret' => '5XXXXXXXXXXXXXX', 'default_graph_version' => 'v2.6', 'persistent_data_handler' => 'session' ]); 

La soluzione per me era cambiare 'secure' => true to false in config / session.php. Ho accidentalmente impostato su true mentre non usavo https in primo luogo.

Per me la soluzione stava rilevando l'exception sostituendo la function Facebook\Exceptions\FacebookSDKException con namespace solo a Exception , perché lo script lo utilizzava già.

 use Facebook\Facebook; // code ... $fb = new Facebook([ 'app_id' => FB_APP_ID, 'app_secret' => FB_APP_SECRET, 'default_graph_version' => 'v2.5', ]); $helper = $fb->getRedirectLoginHelper(); try { $accessToken = $helper->getAccessToken(); } catch (Exception $e) { echo $e->getMessage(); exit; } 

Stavo cercando di implementare l'accesso a Facebook in Symfony con Facebook PHP SDK e ho avuto lo stesso errore "Convalida falsificazione richiesta cross-site fallita. Param richiesto" stato "mancante" .

Ho risolto il problema aggiungendo il parametro persistent_data_handler alla mia istanza di app di Facebook con un gestore personalizzato che implementa PersistentDataInterface di Facebook PHP SDK.

Funziona come un fascino.

 public function facebookCallbackAction(Request $request) { $session = $request->getSession(); $fb = new \Facebook\Facebook([ 'app_id' => $this->container->getParameter('facebook_app_id'), 'app_secret' => $this->container->getParameter('facebook_app_secret'), 'default_graph_version' => 'v2.5', 'persistent_data_handler' => new SymfonyPersistentDataHandler($session), ]); } 

Il mio gestore personalizzato:

 use Facebook\PersistentData\PersistentDataInterface; use Symfony\Component\HttpFoundation\Session\Session; class SymfonyPersistentDataHandler implements PersistentDataInterface { protected $session; protected $sessionPrefix = 'FBRLH_'; public function __construct(Session $session) { $this->session = $session; } public function get($key) { return $this->session->get($this->sessionPrefix . $key); } public function set($key, $value) { $this->session->set($this->sessionPrefix . $key, $value); } } 

Alla fine, dopo tutti questi bei errori, ho risolto tutti i miei problemi con un'altra soluzione, l'esempio dei documenti per gli sviluppatori di Facebook è obsoleto.

SDK V5 e APi 2.4 funzionano come in questo tutorial descritto, il token di accesso deve essere definito

Assicurati di riempire APP-IP | APP-SECRET con le tue credenziali .

Esempio dal tutorial:

 $fb = new Facebook\Facebook([ 'app_id' => 'APP-ID', 'app_secret' => 'APP-SECRET', 'default_graph_version' => 'v2.4', 'default_access_token' => 'APP-ID|APP-SECRET' ]); 

Usa questo e non l'esempio sui documenti per sviluppatori di Facebook.

Divertiti 🙂

Qualunque cosa tu faccia. Non call getAccessToken () più di una volta. Rimuove lo stato dalla session non appena viene chiamato.