Laravel Socialiteを使用して、WebサイトにFacebook接続ボタンを追加しています。時々、コールバックでこのエラーが発生します:
exception 'Laravel\Socialite\Two\InvalidStateException'
in /example/vendor/laravel/socialite/src/Two/AbstractProvider.php:161
私はそれが何を意味するのか分からず、このエラーについてまだ何も発見していません。本当の問題は、それがランダムな例外であるように見えることです(それがなぜ起こるのか理解できないでください)。では、このエラーの意味とそれを回避する方法は?
Laravel 5がAbstractProvider.phpでInvalidStateExceptionを取得する と同じ問題ではないようですが、私の場合はランダムです。
昨夜この問題に遭遇し、次の解決策で解決しました。
私の問題の詳細については、私は持っています
AbstractProvider.php行182のInvalidStateException
関数handleProviderCallback()
で、Facebookログインからリダイレクトして戻る場合。それはあなたの問題と同じようです。
さらに、www
なしでサイトを開くと問題が発生することがわかりました。 www.mysite.com
でサイトを開くと、問題ありません。最初にChris Townsendの質問への回答で手がかりを得るまで、私の問題はランダムだと思います-ありがとうございます。
ソリューション
config/session.php
を確認します'domain' => null,
です。'domain' => 'mysite.com'
を変更しました。'php artisan cache:clear'
と'composer dump-autoload'
の後、www.mysite.com
とmysite.com
の両方から問題なくログインできます。これらの変更が行われた後にテストするときは、ブラウザからクッキーを必ず削除してください。古いCookieでも問題が発生する可能性があります。
解決済み:
Socialite::driver('google')->stateless()->user()
tl; dr
サードパーティのサービスから返された特定のパラメータstate
を読み取る必要がある場合、stateless
メソッドを使用してこのチェックを回避するようにSocialiteを設定できます。
Socialite::driver($provider)->stateless();
Socialiteはすでにこの問題を回避する準備ができていると思います。
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);
}
たとえば、state
は、Googleにデータを渡すのに非常に便利です。
パラメーター:state(任意の文字列)
応答を受信すると、アプリケーションに役立つ可能性のある状態を提供します。 Google認証サーバーはこのパラメーターを往復するため、アプリケーションは送信した値と同じ値を受け取ります。考えられる用途には、ユーザーをサイト内の正しいリソースにリダイレクトすることや、クロスサイトリクエストフォージェリの軽減が含まれます。
参照: https://developers.google.com/identity/protocols/OAuth2UserAgent#overview
storage/framework/sessions
フォルダーのアクセス権も確認してください。
私の場合、このフォルダーは新しいLaravelプロジェクトでは空であるため、GITリポジトリーへの最初のコミット中は除外されています。その後、実稼働サーバーで手動で作成しましたが、明らかに間違ったアクセス権で作成されたため、セッションドライバーに対して書き込み可能ではありませんでした('file'
に設定した場合)。
ブラウザでFacebookの代わりにFacebookアプリを使用してモバイルWeb経由でログインすると、このエラーが発生しました。 Facebookアプリは、ログイン後に現在のブラウザーではなくFacebookブラウザーを使用するため、以前の状態を認識しません。
try {
$socialite = Socialite::driver($provider)->user();
} catch (InvalidStateException $e) {
$socialite = Socialite::driver($provider)->stateless()->user();
}
InvalidStateException
はニシンであり、真の根本原因は他のバグです。モデルの$fillable
配列に新しいフィールドを追加していないことに気付くまでに、12時間かかりました。$provider->user()
リクエストごとに1回だけ呼び出すことができますその関数の内部 がhasInvalidState()
を呼び出し、それが 削除 セッションからの「状態」エントリ。 $provider->user()
を複数回呼び出していることに気づくまでに数時間かかりました。一度だけ呼び出して、結果を変数に保存する必要がありました。私は同じ問題を抱えていて、この問題を解決するためにキャッシュをクリアしただけでした。このコマンドを実行して、プロセスを再度開始しました。
php artisan cache:clear
この答えが誰かに役立つことを願っています。
私の場合、User
クラスの$fillable
配列のパラメーターが欠落していることが原因でした。不足しているパラメーターをすべて追加すると、正常に動作し始めました。
私は同様の問題がありました、私は持っています
InvalidStateException in AbstractProvider.php line 182
関数handleProviderCallback()
で、Facebookログインからリダイレクトして戻るとき。それはあなたの問題と同じようです。
さらに、www
なしでサイトを開くと、問題が発生することがわかりました。 www.mysite.com
でサイトを開くと、問題ありません。最初、質問に対するクリス・タウンゼンドの回答で手がかりを得るまで、私の問題はランダムだと思います。
ソリューション
Wwwルートに移動し、laravelファイルconfig/session.php
を確認します。セッションSession Cookie Domain
を確認してください。デフォルト設定は
'domain' => null,
に変更を加えました
'domain' => 'mysite.com'
php artisan cache:clear
and composer dump-autoload
の後、www.mysite.comおよびmysite.comの両方から問題なくログインできます。
これらの変更が行われた後にテストするときは、ブラウザからクッキーを必ず削除してください。古いCookieでも問題が発生する可能性があります。
それでも助けが必要な場合は、私のコードを使用できます。 2つのルートを作成し、ユーザーテーブルを更新するだけです。 Facebookのユーザーからパスワードを取得できないため、パスワードをヌル可能にすることを忘れないでください。私のコントローラーのコード:
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');
}
これは私のためにそれを解決しました$request->session()->put('state',Str::random(40)); $user = Socialite::driver('github')->stateless()->user();
モバイルでWebを開き、電話でFacebookアプリケーションによるダイアログを開いたときにのみ、同じことが起こります。
これは、Facebook APIからの応答を取得するためにFacebookアプリを開くと、Cookieが失われるためです。ステートレスになりました。次に、socialite
要求を回避するために、stateless
がすでに作成されているオプションを使用します。
$user = Socialite::driver($provider)->stateless()->user();
私にはうまくいきました。それがあなたを助けることを願っています
ソリューションを入手-2018年11月更新
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());
}
SESSION DRIVERをデータベースとして無効化するだけでこれを修正しました...このドライバーを修正しようとして数時間後、ファイルドライバーは正常に機能しました...