Facebook PHP SDK 5 :: API 2.4 :: Falha na validação de falsificação de solicitação entre sites. Parâmetro requerido “estado” faltando

Eu fiz um script PHP muito simples, apenas para tentar fazer o login via Facebook e obter um accessToken. Mas quando eu tento o seguinte código, recebo uma Exceção do SDK: “Falha na validação de falsificação de solicitação entre sites. Exigido param “estado” faltando. ».

Aqui está o meu código:

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
\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 'Log in with Facebook!'; } } exit;

Eu tive que adicionar essas linhas em alguns servidores:

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

Recebo esse erro aleatoriamente, dependendo da configuração do servidor.

Se você estiver usando uma versão “www” do seu site para gerar o link de login e você será redirecionado para a versão não-www, você entrará em problemas com sua session. Portanto, assegure-se de acessar a versão www do seu site e, em seguida, definir o URL de retorno de chamada para a mesma versão www. Além disso, você pode definir redirecionamentos permanentes na configuração do servidor para garantir que qualquer pessoa acessando seu site da versão não-www seja redirecionada para a versão www ou vice-versa.

session_start () no início dos dois scripts. Eu obtive solução a partir daqui: https://github.com/facebook/facebook-php-sdk-v4/issues/473

você recebe esse erro se o nome do host de origem for diferente do nome do host alvo uma vez autenticado.

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

com esta afirmação, se o visitante em seu site usasse o site http://www.wewebsite.com/ o erro de cross-site será gerado.

Você deve garantir que a origem e o nome do host alvo sejam exatamente os mesmos, incluindo o eventual prefixo www.

Versão fixa:

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

Eu também encontrei o mesmo problema e depois de pesquisar no stackoverflow colocando linha

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

acima resolveu meu problema

 $helper = $fb->getRedirectLoginHelper(); 

Configurar [PersistentDataHandler] explicitamente antes de obter seus tokens irá garantir que o pedido seja um sucesso. Abaixo mostra como obter $ _GET [‘estado’] e simplesmente injetá-lo no “para ser usado [helper]” no Symfony 2.x | 3.x

Eu tive exatamente o mesmo problema que o OP e isso corrigiu meu 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')); 

Para mim, o problema está resolvido agora apenas iniciando a session adicionando isso:

 session_start(); 

no início de ambos os arquivos (o primeiro arquivo gerando url do Facebook e o arquivo de retorno de chamada: login.php e fb-callback.php ( https://developers.facebook.com/docs/php/howto/example_facebook_login )).

Eu também tive que adicionar isso:

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

no topo de para evitar outro erro não relacionado.

Como eu respondi aqui: Facebook SDK retornou um erro: Falha na validação de falsificação de solicitação entre sites. O parâmetro “estado” da URL e da session não coincide

você precisa ter certeza de que seu recurso nativo de session PHP esteja configurado corretamente.

Laravel 5.2

Eu também tenho esse erro “Falha na validação de falsificação de solicitação de site cruzado. Falha no estado param” requerido “.

e depois de ler isso por horas. Eu tentei mudar o script do fornecedor.

no vendor\facebook\php-sdk-v4\src\Facebook\Helpers\FacebookRedirectLoginHelper.php na linha 123, eu mudo este script:

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

em (eu adiciono Session::put('state', $state); )

 private function makeUrl($redirectUrl, array $scope, array $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 na linha 234, mudo esse 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.'); } } 

em (eu adicionei $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.'); } } 

Isso é tudo o que eu fiz. e o erro desapareceu.

Encontrei um problema semelhante e encontrei a solução de Nanang Koesharwanto. É mais como quirk como modificação de arquivos de origem no diretório do fornecedor é uma idéia muito ruim. Então, aqui está o truque.

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

Se falhar, use Session; no seu controlador.

Esta é uma questão comum que muitas pessoas enfrentam no FB Api. Este é apenas um problema de SESSÃO. Para resolver este problema, adicione algum código como.

No script de retorno de chamada geralmente fb-callback.php adicione “session_start ();” Antes de include o arquivo de autoload do Facebook. e então “$ _SESSION [‘FBRLH_state’] = $ _ GET [‘state’];” depois do “$ helper = $ fb-> getRedirectLoginHelper ();” linha.

Exemplo:

 getRedirectLoginHelper(); $_SESSION['FBRLH_state']=$_GET['state']; /*Add This*/ try { $accessToken = $helper->getAccessToken(); } ?> 

O problema real aqui foi a codificação do meu arquivo PHP. Eu usei UTF8, mas deveria ter sido UTF8 sem lista de materiais.

O efeito colateral da codificação incorreta foi que minha SESSÃO não estava funcionando corretamente e, em seguida, o SDK não conseguiu recuperar as informações necessárias para funcionar corretamente.

Um relatório de erro corretamente configurado teria dito que havia um problema direto.

Eu acho que podemos preencher esse bug na categoria “noob”. Mas ainda assim, acho que pode ser útil para outros noobs como eu.

Finalmente, olhando para o código do FB, descobri que o problema “Falha na validação da falsificação do pedido do site cruzado”. O parâmetro requerido “faltando” e similares são causados ​​pela variável PHP $ _SESSION [‘FBRLH_state’] que por algum motivo “estranho” quando FB chama o arquivo de retorno de login.

Para resolvê-lo, eu armazeno essa variável “FBRLH_state” APÓS a chamada da function $ helper-> getLoginUrl (…). É muito importante fazer somente após a chamada desta function devido a estar dentro desta function quando a variável $ _SESSION [‘FBRLH_state’] é preenchida.

Abaixo de um exemplo do meu código no 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 no login-callback.php antes de chamar todos os códigos FB:

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

Por último, mas não menos importante, lembre-se também de include o código para a session do PHP, então …

 if(!session_id()) { session_start(); } ... ... ... ...  

Espero que esta resposta possa ajudá-lo a economizar 8-10 horas de trabalho 🙂 Bye, Alex.

Você precisa garantir que a session seja iniciada antes do script ser executado. mas, novamente, lançará uma 443: Network is unreachable se você iniciar uma session novamente no mesmo script. Espero que isso ajude alguém.

Eu apenas usei if (session_status() == PHP_SESSION_NONE){ session_start(); } if (session_status() == PHP_SESSION_NONE){ session_start(); }

Para aqueles de vocês que usam cakephp 3.x e tenham esse problema e você não tem idéia de como resolvê-lo. Adicione session_start (); no início do seu método de autenticação e retorno de chamada.

 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(); 

Para mim, isso estava acontecendo devido a ‘persistent_data_handler’ . Ao adicionar isso na configuração do Facebook, consegui fazê-lo funcionar.

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

A correção para mim era mudar 'secure' => true para false em config / session.php. Eu acidentalmente configurei isso como verdade enquanto não uso o https em primeiro lugar.

Para mim, a solução estava travando a exceção, substituindo o namespaced Facebook\Exceptions\FacebookSDKException para apenas Exception , porque o script já o usava.

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

Eu estava tentando implementar o login do Facebook no Symfony com o Facebook SDK do PHP e eu tive o mesmo erro “Falha na validação de falsificação de solicitação de site cruzado. Estado de parametrização necessário” .

Resolvi o problema ao adicionar o parâmetro persistent_data_handler à instanciação do meu aplicativo do Facebook com um manipulador personalizado que implementa o PersistentDataInterface do Facebook SDK do Facebook.

Funciona como um encanto.

 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), ]); } 

Meu manipulador personalizado:

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

Finalmente, depois de todos esses erros agradáveis, reparei todos os meus problemas com outra solução, o exemplo dos documentos do desenvolvedor do Facebook está desatualizado.

SDK V5 e APi 2.4 funcionam como neste tutorial descrito, o token de access precisa ser definido

Certifique-se de preencher APP-IP | APP-SECRET com suas credenciais .

Exemplo do 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' ]); 

Use isso e não o exemplo em documentos do facebook do desenvolvedor.

Diverta-se 🙂

O que quer que você faça. Apenas não ligue para getAccessToken () mais de uma vez. Ele remove o estado da session assim que é chamado.