可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm using Laravel Socialite to add a Facebook connect button on a website. Sometimes, I've got this error on callback:
exception 'Laravel\Socialite\Two\InvalidStateException' in /example/vendor/laravel/socialite/src/Two/AbstractProvider.php:161
I don't know what it mean and did not found anything yet about this error. The real problem is it seems to be a random exception (don't understood why it happens). So what this error means and how to avoid it?
It seems it's not the same problem as Laravel 5 geting InvalidStateException in AbstractProvider.php, cause in my case it's random.
回答1:
I ran into this issue last night and solve it with the following solution.
More information on my issue, I've got
InvalidStateException in AbstractProvider.php line 182
in the function handleProviderCallback()
when it re-direct back from Facebook login. It seems to be the same as your issue.
Furthermore I found my issue occurs when I open my site without www
. When I open my site with www.mysite.com
- no problem. At first I think my issue is random until I've got the clue by Chris Townsend's reply to the question - Thank you very much.
The Solution
- Go to your www root, check the laravel file
config/session.php
- Check session Session Cookie Domain The default configuration is
'domain' => null,
I made a change to 'domain' => 'mysite.com'
. - After
'php artisan cache:clear'
and 'composer dump-autoload'
, I can login with no issue from both www.mysite.com
and mysite.com
Be sure to delete your cookies from browser when testing it after these modifications are done. Old cookies can still produce problems.
回答2:
Resolved :
Socialite::driver('google')->stateless()->user()
回答3:
tl;dr
If you need to read a given parameter state
returned by a thirdparty service, you can set Socialite to avoid this checking with the stateless
method:
Socialite::driver($provider)->stateless();
I think Socialite is already prepared to avoid this issue.
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; // request->getSession()->pull('state'); return ! (strlen($state) > 0 && $this->request->input('state') === $state); }
For instance, state
is very useful to pass data throught google:
Parameter: state (Any string)
Provides any state that might be useful to your application upon receipt of the response. The Google Authorization Server round-trips this parameter, so your application receives the same value it sent. Possible uses include redirecting the user to the correct resource in your site, and cross-site-request-forgery mitigations.
ref: https://developers.google.com/identity/protocols/OAuth2UserAgent#overview
回答4:
Also check access right on your storage/framework/sessions
folder.
In my case, since this folder is empty in new Laravel project, it has been left out during initially commit to the GIT repository. Afterwards I created it manually on production server, but obviously with the wrong access rights, hence it was not writable for the session driver (when set to 'file'
).
回答5:
If you still need help you can use my code, it works for me. You just need to create two routes and update the users table. Don't forget to make password nullable, since you won't get one from the facebook users The code in my 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'); }
回答6:
I fixed this just disabling the SESSION DRIVER as database... file driver worked fine for me after hours trying to fix this s...
回答7:
I want to share you my solution . I go to my AbstractProvider.php
file and in the line of problem
public function user() { if ($this->hasInvalidState()) { throw new InvalidStateException; } // ... }
I stop the throw new InvalidStateException
and call the redirect function like that:
public function user() { if ($this->hasInvalidState()) { $this->redirect(); // throw new InvalidStateException; } // ... }