J'ai fait un script très simple PHP, juste pour essayer de se connecter via Facebook et obtenir un accessToken. Mais lorsque j'essaie le code suivant, je reçois une exception du SDK: «La validation de la falsification d'une requête intersite a échoué. Param requis "état" manquant. ».
Voici mon code:
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;
J'ai dû ajouter ces lignes sur certains serveurs:
$helper = $fb->getRedirectLoginHelper();
if (isset($_GET['state'])) {
$helper->getPersistentDataHandler()->set('state', $_GET['state']);
}
Je reçois cette erreur au hasard, en fonction de la configuration du serveur.
session_start () au début des deux scripts. J'ai eu la solution à partir d'ici: https://github.com/facebook/facebook-php-sdk-v4/issues/473
Si vous utilisez une version "www" de votre site pour générer le lien de connexion et que vous êtes redirigé vers la version non-www, vous rencontrerez des problèmes avec votre session. Assurez-vous donc d’accéder à la version www de votre site, puis définissez l’URL de rappel sur la même version www. Vous pouvez également définir des redirections permanentes dans la configuration de votre serveur pour vous assurer que toute personne accédant à votre site à partir de la version non www sera redirigée vers la version www ou vice versa.
J'ai également rencontré le même problème et après des recherches sur stackoverflow Putting line
$_SESSION['FBRLH_state']=$_GET['state'];
ci-dessus a résolu mon problème
$helper = $fb->getRedirectLoginHelper();
C’est un problème courant auquel de nombreuses personnes sont confrontées dans FB Api. ce n'est qu'un problème de SESSION. Pour résoudre ce problème, ajoutez du code tel que.
Sur le script de rappel habituellement fb-callback.php ajoute "session_start ();" juste avant d'inclure le fichier de chargement automatique de facebook. et ensuite "$ _SESSION ['FBRLH_state'] = $ _ GET ['state'];" après le "$ helper = $ fb-> getRedirectLoginHelper ();" ligne.
Exemple :
<?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();
} ?>
Définir explicitement [PersistentDataHandler] avant d’obtenir vos jetons garantira le succès de la demande. Vous trouverez ci-dessous comment récupérer $ _GET ['state'] et l'injecter simplement dans le "à utiliser [assistant]" sur Symfony 2.x | 3.x
J'ai eu exactement le même problème que l'O.P. et cela a résolu mon problème.
//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'));
vous recevez cette erreur si votre nom d’hôte Origin est différent du nom d’hôte cible une fois authentifié.
$loginUrl = $helper->getLoginUrl('http://mywebsite.com/myapp/index.php', $permissions);
avec cette déclaration, si le visiteur de votre site Web a utilisé http://www.mywebsite.com/ , l'erreur intersite sera générée.
Vous devez vous assurer que l'origine et le nom d'hôte cible sont exactement les mêmes, y compris le préfixe www éventuel.
Version fixe:
$loginUrl = $helper->getLoginUrl('http://'.$_SERVER['SERVER_NAME'].'/myapp/index.php', $permissions);
J'ai rencontré un problème similaire et j'ai trouvé la solution de Nanang Koesharwanto. Cela ressemble plus à un hasard, car la modification des fichiers source dans le répertoire du fournisseur est une très mauvaise idée. .__ Alors, voici le truc.
public function callback(Request $request)
{
$this->helper->getPersistentDataHandler()->set('state', $request->state);
return $this->helper->getAccessToken();
}
Si cela échoue, mettez use Session;
dans votre contrôleur.
J'essayais d'implémenter la connexion à Facebook dans Symfony avec le kit de développement logiciel PHP et j'avais la même erreur "La validation de la demande de cross-site a échoué. Param requis" état "manquant".
J'ai résolu le problème en ajoutant persistent_data_handler paramètre à mon instanciation de l'application facebook avec un gestionnaire personnalisé qui implémente le SDK PersistentDataInterface de Facebook PHP.
Fonctionne comme un charme.
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),
]);
}
Mon gestionnaire personnalisé:
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);
}
}
Laravel 5.2
J'ai aussi cette erreur "Échec de la validation de la requête intersite. Param requis" état "manquant".
et après avoir lu ceci pendant des heures. J'ai essayé de changer le script du vendeur.
dans vendor\facebook\php-sdk-v4\src\Facebook\Helpers\FacebookRedirectLoginHelper.php
à la ligne 123, je modifie ce 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);
}
dans (j'ajoute 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);
}
et sur la ligne 234, je change ce 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.');
}
}
dans (j'ai ajouté $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.');
}
}
c'est tout ce que j'ai fait. et l'erreur est partie.
Pour moi, le problème est résolu maintenant en démarrant la session en ajoutant ceci:
session_start();
au début des deux fichiers (le premier fichier générant l'URL facebook et le fichier de rappel: login.php et fb-callback.php ( https://developers.facebook.com/docs/php/howto/example_facebook_login ) ).
J'ai aussi dû ajouter ceci:
$config['app_id'] = 'myapp_id';
en haut pour éviter une autre erreur non liée.
Comme je l’ai répondu ici: Le SDK de Facebook a renvoyé une erreur: la validation de la falsification de requête intersite a échoué. Le paramètre "state" de l'URL et de la session ne correspond pas
vous devez vous assurer que votre fonction de session native PHP est correctement définie.
Enfin, en examinant le code FB, j’ai découvert que le problème "La validation de la demande intersite a échoué. Les paramètres" état "manquant" et autres sont causés par la variable PHP $ _SESSION ['FBRLH_state' " étrange "lorsque FB appelle le fichier login-callback.
Pour le résoudre, je stocke cette variable "FBRLH_state" APRES l'appel de la fonction $ helper-> getLoginUrl (...). Il est très important de ne le faire qu'après l'appel de cette fonction car c'est à l'intérieur de celle-ci que la variable $ _SESSION ['FBRLH_state'] est renseignée.
Ci-dessous un exemple de mon code dans le 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);
Et dans le fichier login-callback.php avant d'appeler tout le code FB:
foreach ($_COOKIE as $k=>$v) {
if(strpos($k, "FBRLH_")!==FALSE) {
$_SESSION[$k]=$v;
}
}
Dernier point, mais non le moindre, n'oubliez pas d'inclure également du code pour la session PHP.
if(!session_id()) {
session_start();
}
...
...
...
...
<?php session_write_close() ?>
J'espère que cette réponse pourra vous aider à économiser 8 à 10 heures de travail:) Bye, Alex.
Le vrai problème ici était l'encodage de mon fichier PHP. J'ai utilisé UTF8, mais cela aurait dû être UTF8 sans nomenclature.
L'inconvénient d'un mauvais encodage était que ma SESSION ne fonctionnait pas correctement, ce qui empêchait le SDK de récupérer les informations nécessaires pour fonctionner correctement.
Un rapport d'erreur correctement configuré aurait indiqué qu'il y avait un problème directement.
Je pense que nous pouvons combler ce bogue dans la catégorie "noob". Mais encore, je pense que cela peut être utile à d'autres noobs comme moi.
Si session_start () ne résout toujours pas le problème, vous insérez un mauvais URI dans l'URI de redirection OAuth valide de votre application de développeur Facebook.
Pour résoudre: Tout d’abord, allez à votre fb-callback.php, recherchez l’URI que vous avez mis dans la fonction d’entête, exemple: entête ("Location: https: //localhost/home.php "). Ensuite, accédez à vos applications de développement Facebook, puis dans la barre latérale, cliquez sur Connexion Facebook, sous l'onglet Produits, puis sur Paramètres. Dans l'URI de redirection OAuth valide, ajoutez l'URI que vous avez mis dans l'en-tête. De mon exemple, je vais mettre https: //localhost/home.php .
J'espère que cela t'aides.
vous devez vous assurer que la session démarre avant l'exécution du script. mais là encore, un 443: Network is unreachable
sera lancé si vous démarrez à nouveau une session sur le même script. espérons que cela aide quelqu'un.
Je viens d'utiliser if (session_status() == PHP_SESSION_NONE){ session_start(); }
Pour ceux d'entre vous qui utilisent cakephp 3.x et ont ce problème et vous ne savez pas comment le résoudre. Ajouter session_start (); au début de votre méthode d'authentification et de rappel.
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();
Le correctif pour moi était de changer 'secure' => true
en false
dans config/session.php . Je l'avais accidentellement mis à true, alors que je n'utilisais pas https.
Pour moi, cela était dû à 'persistent_data_handler' . En ajoutant ceci dans la configuration Facebook, j'ai pu le faire fonctionner.
session_start();
$fb = new Facebook\Facebook([
'app_id' => '6XXXXXXXXX',
'app_secret' => '5XXXXXXXXXXXXXX',
'default_graph_version' => 'v2.6',
'persistent_data_handler' => 'session'
]);
Pour moi, la solution consistait à intercepter l'exception en remplaçant le Facebook\Exceptions\FacebookSDKException
namespaced par simplement Exception
, car le script l'avait déjà utilisée.
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;
}