web-dev-qa-db-fra.com

Le jeton d'état CSRF ne correspond pas à un FB fourni PHP SDK 3.1.1 Oauth 2.0

Les journaux de mon serveur indiquent une erreur "Le jeton d'état CSRF ne correspond pas à celui fourni" qui semble se produire pour presque tous les utilisateurs. Cependant, les utilisateurs sont créés et/ou authentifiés et je peux récupérer les informations de l'utilisateur. J'utilise un serveur Linux avec Apache. J'utilise également le dernier PHP SDK v.3.1.1 de Facebook. Quelqu'un peut-il me dire pourquoi cela se produit et comment y remédier?

23
Harry Andrei

J'ai eu un problème similaire la semaine dernière et je l'ai retrouvé dans le champ state qui est écrasé par plusieurs appels à getLoginUrl(). Chaque fois que vous appelez getLoginUrl(), un nouveau jeton state est généré dans le SDK et stocké dans le $_SESSION (il s’agit simplement d’une valeur aléatoire). Ainsi, si vous l’appelez deux fois et que l’utilisateur utilise le premier lien pour se connecter, réinitialisez le jeton state interne du SDK et vous obtiendrez cette erreur dans vos journaux.

Le SDK recherche le même jeton state dans l'URL qui revient après que Facebook a autorisé l'utilisateur et les redirige vers votre site. S'il ne correspond pas, il enregistre cette erreur (voici un lien vers source ). .

35
jches

Le code du Kit de développement logiciel (SDK) Facebook contient un bogue lorsqu’il vérifie deux fois les jetons dans le même gestionnaire. 

J'ai édité la fonction getCode de facebook.php comme ceci: 

protected function getCode() {
    if (!isset($_REQUEST['code']) || !isset($_REQUEST['state']) || $this->state === null) {
      return false;
    }
    if ($this->state === $_REQUEST['state']) {
        // CSRF state has done its job, so clear it
        $this->state = null;
        $this->clearPersistentData('state');
        return $_REQUEST['code'];
    }
    self::errorLog('CSRF state token does not match one provided.');

    return false;
}

pour être plus clair et ne pas déclarer jeton invalide si appelé deux fois.

Pour être clair, la fonction peut être appelée deux fois sur le même gestionnaire d’URL si, par exemple: 

$facebook->getUser(); et ensuite dans le même gestionnaire $facebook->getLogoutUrl(), le getCode() est appelé deux fois, ce qui entraîne un message d'erreur non valide.

8
Jimmy Kane

Eh bien, j’ai rencontré ce problème une fois et j’ai eu un problème avec les paramètres state & code dans l’URL - mon fichier .htaccess ne les transmettait pas.

Je suppose que vous rencontrez le même problème.

Le jeton d'état CSRF ne correspond pas à celui fourni

J'espère que cela t'aides

3
Roni

Remarque supplémentaire - bien que cela ne soit pas indiqué dans la documentation de l'API PHP de Facebook, vous devez configurer Apache pour les sessions PHP pour que le processus de connexion fonctionne. Cela s’est avéré être le problème que nous avons rencontré lorsque nous avons reçu le "jeton d’état CSRF ne correspond pas à celui fourni". 

Assurez-vous que si vous utilisez un pool de serveurs configuré pour utiliser memcache pour les informations de session, sinon Apache écrira les informations de session localement et si la prochaine demande ne va pas au même serveur, vous obtiendrez l'état "CSRF Le jeton ne correspond pas à celui fourni ". 

C’est une de ces choses qui a fonctionné comme un charme dans un environnement de développement (avec un serveur) mais qui a échoué en production. 

Nous avons également dû reconfigurer nos paramètres CDN pour nous assurer de passer par le cookie de session PHP. 

2
Joanne Garlow

J'ai eu le même problème. C'est facile. Ne pas appeler 

$fbLoginUrl = $facebook->getLoginUrl(...);

avant 

$fbUser = $facebook->getUser();

sinon, vous obtiendrez l'erreur "Le jeton d'état CSRF ne correspond pas à celui fourni.".

2
spurs50

Pour ajouter un peu à la réponse de chesles, ce problème peut survenir si vous jouez avec les fonctions session_start () - session_write_close (), comme je l’ai fait.

S'il n'y a pas de session démarrée lorsque vous demandez le loginUrl, vous obtiendrez cette erreur.

Sidenote: Pourquoi se donner la peine d’arrêter la session?

Les scripts qui utilisent des sessions s’arrêtent, car ils attendent que le tableau de sessions soit disponible.

Imaginez que vous ayez une application populaire, avec des milliers d'utilisateurs, et ayez une action (un script php) où vous postez une image .

--démarrage de la session en haut du script

--connecting to facebook

--créer l'image

--sharing l'image avec l'appel api

--script end, la session se ferme automatiquement

En faisant cela, la session sera utilisée par le script pendant longtemps sans raison . Soyez prudent avec de tels scripts, utilisez quelque chose comme ceci à la place:

--la session de démarrage juste avant l'endroit où vous créez l'objet facebook

--connecting to facebook

--closing session avec session_write_close (), le tableau de session est disponible, d'autres scripts peuvent se charger

--créer l'image

--sharing l'image avec l'appel api/* Il pense que cela n'a pas besoin d'une session. * /

--script end, la session est déjà fermée manuellement.

À votre santé.

2
ZeeCoder

L'état et le code CSRF sont vérifiés en utilisant des sessions locales, je parie que vous devez vérifier votre session.save_handler dans votre php.ini, et s'il fonctionne correctement.

0
Antoine Baqain

si vous utilisez les redirections .htaccess mod rewrite sur votre page, utilisez le [QSA] (Query String Append) à la fin des lignes pour conserver les variables GET, sinon vous avez perdu la variable $ code, nécessaire à la connexion à Facebook. 

0
askdig