web-dev-qa-db-fra.com

Laravel Socialite: InvalidStateException

J'utilise Laravel Socialite pour ajouter un bouton de connexion Facebook sur un site Web. Parfois, j'ai cette erreur sur le rappel:

exception 'Laravel\Socialite\Two\InvalidStateException' 
in /example/vendor/laravel/socialite/src/Two/AbstractProvider.php:161

Je ne sais pas ce que cela signifie et je n'ai encore rien trouvé à propos de cette erreur. Le vrai problème est que cela semble être une exception aléatoire (je ne comprends pas pourquoi cela se produit). Alors qu'est-ce que cette erreur signifie et comment l'éviter?

Il semble que ce ne soit pas le même problème que Laravel 5: obtenir InvalidStateException dans AbstractProvider.php , car dans mon cas, il est aléatoire.

40
rap-2-h

J'ai rencontré ce problème hier soir et je l'ai résolu avec la solution suivante.

Plus d'informations sur mon problème, j'ai 

InvalidStateException dans la ligne AbstractProvider.php 182

dans la fonction handleProviderCallback() quand il est redirigé depuis la connexion à Facebook. Cela semble être la même chose que votre problème.

De plus, j'ai constaté que mon problème survient lorsque j'ouvre mon site sans www. Quand j'ouvre mon site avec www.mysite.com - pas de problème. Au début, je pense que mon problème est aléatoire jusqu’à ce que je trouve la réponse de Chris Townsend à la réponse de/à la question - Merci beaucoup.

La solution

  1. Allez à la racine www, consultez le fichier laravel config/session.php
  2. Vérifier la session Domaine du cookie de session La configuration par défaut est 'domain' => null, J'ai modifié 'domain' => 'mysite.com'.
  3. Après 'php artisan cache:clear' et 'composer dump-autoload', je peux me connecter sans problème à la fois avec www.mysite.com et mysite.com.

Assurez-vous de supprimer vos cookies du navigateur lorsque vous les testez une fois ces modifications terminées. Les vieux cookies peuvent toujours causer des problèmes.

60
Chaochana

Résolu:

Socialite::driver('google')->stateless()->user()
35
Nguyen Phuong

tl; dr

Si vous devez lire un paramètre donné state renvoyé par un service tiers, vous pouvez définir Socialite pour éviter cette vérification avec la méthode stateless:

   Socialite::driver($provider)->stateless();

Je pense que Socialite est déjà prêt à éviter ce problème.

https://github.com/laravel/socialite/blob/2.0/src/Two/AbstractProvider.php#L77

 /**
 * Indicates if the session state should be utilized.
 *
 * @var bool
 */
protected $stateless = false;

https://github.com/laravel/socialite/blob/2.0/src/Two/AbstractProvider.php#L374

/**
 * Indicates that the provider should operate as stateless.
 *
 * @return $this
 */
public function stateless()
{
    $this->stateless = true;
    return $this;
}

https://github.com/laravel/socialite/blob/2.0/src/Two/AbstractProvider.php#L222

/**
 * Determine if the current request / session has a mismatching "state".
 *
 * @return bool
 */
protected function hasInvalidState()
{
    if ($this->isStateless()) {
        return false; // <--------
    }
    $state = $this->request->getSession()->pull('state');
    return ! (strlen($state) > 0 && $this->request->input('state') === $state);
}

Par exemple, state est très utile pour transmettre des données à Google:

Paramètre: état (toute chaîne)
Fournit tout état pouvant être utile à votre demande dès réception de la réponse. L'autorisation Google Le serveur effectue l'aller-retour ce paramètre pour que votre application reçoive le même valeur qu'il a envoyé. Les utilisations possibles incluent la redirection de l'utilisateur vers le fichier ressource correcte sur votre site et falsification inter-sites. les atténuations.

ref: https://developers.google.com/identity/protocols/OAuth2UserAgent#overview

10
Igor Parra

Vérifiez également les droits d’accès sur votre dossier storage/framework/sessions

Dans mon cas, comme ce dossier est vide dans le nouveau projet Laravel, il a été omis lors de la validation initiale dans le référentiel GIT. Ensuite, je l’ai créé manuellement sur le serveur de production, mais avec les mauvais droits d’accès, c’est pourquoi il n’était pas accessible en écriture pour le pilote de session (défini sur 'file').

2
Greegus

J'ai eu le même problème et je viens de vider le cache pour résoudre ce problème. Je viens d'exécuter cette commande et de relancer le processus.

php artisan cache:clear

J'espère que cette réponse peut aider quelqu'un.

1
AboElnouR

Dans mon cas, cela est dû à l'absence de paramètres dans le tableau $fillable dans la classe User. Quand j'ai ajouté tous les paramètres manquants, cela a commencé à fonctionner correctement ..

1
Jan Kotas

Je ne rencontrais cette erreur que lorsque je me connectais via le Web mobile avec l'application Facebook au lieu de Facebook dans le navigateur. L'application facebook utilise le navigateur facebook après la connexion au lieu de votre navigateur actuel, donc ignore l'état précédent.

try {
    $socialite = Socialite::driver($provider)->user();
} catch (InvalidStateException $e) {
    $socialite = Socialite::driver($provider)->stateless()->user();
}
0
makhag

J'ai eu un problème similaire, j'ai

InvalidStateException in AbstractProvider.php line 182

dans la fonction handleProviderCallback() quand il est redirigé à partir de la connexion à Facebook. Cela semble être la même chose que votre problème.

De plus, j'ai constaté que mon problème survient lorsque j'ouvre mon site sans www. Quand j'ouvre mon site avec www.mysite.com - pas de problème. Au début, je pense que mon problème est aléatoire jusqu'à ce que je connaisse la réponse de Chris Townsend à la question.

La solution

Allez à la racine www, consultez le fichier laravel config/session.php. Vérifiez la session Session Cookie Domain. La configuration par défaut est

'domain' => null,

J'ai changé pour

'domain' => 'mysite.com' 

Après php artisan cache:clear et composer dump-autoload, je peux me connecter sans problème à partir des sites www.mysite.com et mysite.com.

Assurez-vous de supprimer vos cookies du navigateur lorsque vous les testez une fois ces modifications terminées. Les vieux cookies peuvent toujours causer des problèmes.

Si vous avez encore besoin d'aide, vous pouvez utiliser mon code, cela fonctionne pour moi. Il vous suffit de créer deux itinéraires et de mettre à jour la table des utilisateurs. N'oubliez pas de rendre le mot de passe annulable, car vous n'en obtiendrez pas des utilisateurs de Facebook Le code de mon contrôleur:

public function redirectToProvider()
{
    return Socialize::with('facebook')->redirect();
}

public function handleProviderCallback(User $user)
{
    $money = Socialize::with('facebook')->user();

    if(User::where('email', '=', $money->email)->first()){
    $checkUser = User::where('email', '=', $money->email)->first();
    Auth::login($checkUser);
    return redirect('home');
     } 

    $user->facebook_id = $money->getId();
    $user->name = $money->getName();
    $user->email = $money->getEmail();
    $user->avatar = $money->getAvatar();
    $user->save();

    Auth::login($user);
    return redirect('home');

}
0
Itzik Ben Hutta

cela a résolu pour moi 
$request->session()->put('state',Str::random(40)); $user = Socialite::driver('github')->stateless()->user();

0
lacasera

Vous avez la solution - Mise à jour novembre 2018

public function redirectToGoogle(Request $request)
{
    /**
     * @var GoogleProvider $googleDriver
     */
    $googleDriver = Socialite::driver("google");
    return $googleDriver->redirect();
}

public function fromGoogle(Request $request)
{
    try {
/*
Solution Starts ----
*/
        if (empty($_GET)) {
            $t = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY);
            parse_str($t, $output);
            foreach ($output as $key => $value) {
                $request->query->set($key, $value);
            }
        }
/*
Solution Ends ----
*/
        /**
         * @var GoogleProvider $googleDriver
         */
        $googleDriver = Socialite::driver("google");
        print_r($googleDriver->user());
    } catch (\Exception $e) {
        print_r($e->getMessage());
    }
0
Tarinder

J'ai résolu ce problème en désactivant simplement SESSION DRIVER en tant que base de données ... le pilote de fichier fonctionnait parfaitement pour moi.

0
insign