Ich benutze Laravel Socialite, um einer Website eine Facebook-Schaltfläche zum Verbinden hinzuzufügen. Manchmal habe ich diesen Fehler beim Rückruf:
exception 'Laravel\Socialite\Two\InvalidStateException'
in /example/vendor/laravel/socialite/src/Two/AbstractProvider.php:161
Ich weiß nicht was es bedeutet und habe noch nichts über diesen Fehler gefunden. Das eigentliche Problem ist, dass es eine zufällige Ausnahme ist (verstehe nicht, warum es passiert). Was bedeutet dieser Fehler und wie kann er vermieden werden?
Es scheint, dass es nicht das gleiche Problem ist wie Laravel 5 erhält InvalidStateException in AbstractProvider.php , weil es in meinem Fall zufällig ist.
Ich bin gestern Abend auf dieses Problem gestoßen und habe es mit der folgenden Lösung gelöst.
Weitere Informationen zu meiner Ausgabe habe ich
InvalidStateException in AbstractProvider.php-Zeile 182
in der Funktion handleProviderCallback()
, wenn es vom Facebook-Login zurückgeleitet wird. Es scheint das gleiche zu sein wie Ihr Problem.
Außerdem habe ich festgestellt, dass mein Problem auftritt, wenn ich meine Website ohne www
öffne. Wenn ich meine Site mit www.mysite.com
öffne - kein Problem. Zuerst denke ich, dass mein Problem zufällig ist, bis ich die Antwort von Chris Townsend auf die Frage - Vielen Dank habe.
Die Lösung
config/session.php
'domain' => null,
Ich habe eine Änderung an 'domain' => 'mysite.com'
vorgenommen.'php artisan cache:clear'
und 'composer dump-autoload'
kann ich mich ohne Probleme mit www.mysite.com
und mysite.com
einloggen.Stellen Sie sicher, dass Sie Ihre Cookies aus dem Browser löschen, nachdem Sie diese Änderungen vorgenommen haben. Alte Cookies können immer noch Probleme verursachen.
Aufgelöst :
Socialite::driver('google')->stateless()->user()
tl; dr
Wenn Sie einen bestimmten Parameter state
lesen müssen, der von einem Drittanbieterdienst zurückgegeben wird, können Sie Socialite festlegen, um diese Überprüfung mit der stateless
-Methode zu vermeiden:
Socialite::driver($provider)->stateless();
Ich denke, Socialite ist bereits bereit, dieses Problem zu vermeiden.
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);
}
Beispielsweise ist state
sehr nützlich, um Daten über Google zu übergeben:
Parameter: state (beliebige Zeichenfolge)
Stellt jeden Status bereit, der für Ihre .__ nützlich sein könnte. Antrag nach Erhalt der Antwort. Die Google-Autorisierung Der Server rundet diesen Parameter ab, sodass Ihre Anwendung die .__ erhält. den gleichen Wert, den es gesendet hat. Mögliche Verwendungen umfassen das Umleiten des Benutzers an die richtige Ressource in Ihrer Site und Cross-Site-Request-Forgery Milderungen.
ref: https://developers.google.com/identity/protocols/OAuth2UserAgent#overview
Überprüfen Sie auch das Zugriffsrecht in Ihrem storage/framework/sessions
-Ordner.
Da dieser Ordner im neuen Laravel-Projekt leer ist, wurde er in meinem Fall beim ersten Commit an das GIT-Repository ausgelassen. Danach habe ich es manuell auf dem Produktionsserver erstellt, jedoch offensichtlich mit den falschen Zugriffsrechten. Daher war es für den Sitzungstreiber nicht schreibbar (wenn auf 'file'
eingestellt).
InvalidStateException
ein roter Hering und die wahre Ursache ist ein anderer Fehler. Ich brauchte einmal ~ 12 Stunden, um festzustellen, dass ich dem Array $fillable
Im Modell kein neues Feld hinzugefügt hatte.$provider->user()
= kann nur einmal pro Anfrage aufgerufen werden, da das innerhalb dieser FunktionhasInvalidState()
aufruft, das dann - entfernt den 'Status'-Eintrag aus der Sitzung. Es dauerte Stunden, bis mir klar wurde, dass ich $provider->user()
mehrmals aufgerufen habe, als ich es nur einmal hätte aufrufen und das Ergebnis in einer Variablen speichern sollen.Ich hatte das gleiche Problem und ich habe den Cache geleert , um dieses Problem zu lösen. Ich habe diesen Befehl gerade ausgeführt und den Vorgang erneut gestartet.
php artisan cache:clear
Ich hoffe, diese Antwort kann jemandem helfen.
In meinem Fall wurde dies durch fehlende Parameter im $fillable
-Array der User
-Klasse verursacht. Nachdem ich alle fehlenden Parameter hinzugefügt hatte, begann es richtig zu funktionieren.
Dieser Fehler ist nur aufgetreten, wenn ich mich über die mobile App mit der Facebook-App anstelle von Facebook im Browser anmeldete. Die Facebook-App verwendet den Facebook-Browser nach dem Anmelden anstelle Ihres aktuellen Browsers, so dass der vorherige Status nicht bekannt ist.
try {
$socialite = Socialite::driver($provider)->user();
} catch (InvalidStateException $e) {
$socialite = Socialite::driver($provider)->stateless()->user();
}
Ich hatte ein ähnliches Problem
InvalidStateException in AbstractProvider.php line 182
in der Funktion handleProviderCallback()
, wenn es vom Facebook-Login zurückgeleitet wird. Es scheint das gleiche zu sein wie Ihr Problem.
Außerdem habe ich festgestellt, dass mein Problem auftritt, wenn ich meine Website ohne www
öffne. Wenn ich meine Site mit www.mysite.com
öffne - kein Problem. Zuerst denke ich, dass mein Problem zufällig ist, bis ich die Antwort von Chris Townsend auf die Frage erhalten habe.
Die Lösung
Gehen Sie zu Ihrem WWW-Stammverzeichnis, überprüfen Sie die Laravel-Datei config/session.php
. Überprüfen Sie die Sitzung Session Cookie Domain
. Die Standardkonfiguration ist
'domain' => null,
Ich habe eine Änderung an vorgenommen
'domain' => 'mysite.com'
Nach php artisan cache:clear
und composer dump-autoload
kann ich mich unter www.mysite.com und mysite.com ohne Probleme anmelden
Stellen Sie sicher, dass Sie Ihre Cookies aus dem Browser löschen, nachdem Sie diese Änderungen vorgenommen haben. Alte Cookies können immer noch Probleme verursachen.
Wenn Sie immer noch Hilfe benötigen, können Sie meinen Code verwenden. Das funktioniert für mich. Sie müssen nur zwei Routen erstellen und die Benutzertabelle aktualisieren. Vergessen Sie nicht, das Passwort für null zu erklären, da Sie von den Facebook-Benutzern kein Passwort erhalten. Der Code in meinem Controller:
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');
}
das hat es für mich gelöst $request->session()->put('state',Str::random(40));
$user = Socialite::driver('github')->stateless()->user();
Das gleiche passiert nur, wenn ich mein Web auf dem Handy öffne und den Dialog über die Facebook-Anwendung auf meinem Handy öffne.
Ich denke: Das passiert, weil die offene Facebook-App, um eine Antwort von der Facebook-API zu erhalten, ein Cookie verloren hat. es ist staatenlos geworden. Dann benutze ich einfach die Option, dass socialite
bereits gemacht wird, um stateless
Anfragen zu vermeiden.
$user = Socialite::driver($provider)->stateless()->user();
Es hat bei mir funktioniert. hoffe es hilft dir
Habe die Lösung - Update November 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());
}
Ich habe das Problem behoben, indem ich einfach den SESSION DRIVER als Datenbank deaktiviert habe.