php Laravel 社交名媛:InvalidStateException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30660847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel Socialite: InvalidStateException
提问by rap-2-h
I'm using Laravel Socialite to add a Facebook connect button on a website. Sometimes, I've got this error on callback:
我正在使用 Laravel Socialite 在网站上添加 Facebook 连接按钮。有时,我在回调中遇到此错误:
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.
这似乎与Laravel 5 在 AbstractProvider.php 中获取 InvalidStateException 不同,因为在我的情况下它是随机的。
回答by Chaochana
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
AbstractProvider.php 第 182 行中的 InvalidStateException
in the function handleProviderCallback()
when it re-direct back from Facebook login. It seems to be the same as your issue.
在函数中,handleProviderCallback()
当它从 Facebook 登录重定向回来时。好像和你的问题一样。
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.
此外,我发现当我打开我的网站而没有www
. 当我打开我的网站时www.mysite.com
- 没问题。起初我认为我的问题是随机的,直到我从Chris Townsend对问题的回答中得到了线索- 非常感谢。
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 bothwww.mysite.com
andmysite.com
- 转到您的 www 根目录,检查 Laravel 文件
config/session.php
- 检查 session Session Cookie Domain 默认配置是
'domain' => null,
我对'domain' => 'mysite.com'
. - 在
'php artisan cache:clear'
和之后'composer dump-autoload'
,我可以毫无问题地登录www.mysite.com
和mysite.com
Be sure to delete your cookies from browser when testing it after these modifications are done. Old cookies can still produce problems.
在完成这些修改后进行测试时,请务必从浏览器中删除您的 cookie。旧的 cookie 仍然会产生问题。
回答by Nguyen Phuong
Resolved :
解决 :
Socialite::driver('google')->stateless()->user()
回答by Igor Parra
tl;dr
tl;博士
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:
如果您需要读取state
第三方服务返回的给定参数,您可以设置 Socialite 以避免使用以下stateless
方法进行检查:
Socialite::driver($provider)->stateless();
I think Socialite is already prepared to avoid this issue.
我认为 Socialite 已经准备好避免这个问题。
https://github.com/laravel/socialite/blob/2.0/src/Two/AbstractProvider.php#L77
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
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
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);
}
For instance, state
is very useful to pass data throught google:
例如,state
通过谷歌传递数据非常有用:
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.
参数:state (Any string)
提供在收到响应后可能对您的应用程序有用的任何状态。Google 授权服务器来回传递此参数,因此您的应用程序会收到它发送的相同值。可能的用途包括将用户重定向到站点中的正确资源,以及跨站点请求伪造缓解措施。
ref: https://developers.google.com/identity/protocols/OAuth2UserAgent#overview
参考:https: //developers.google.com/identity/protocols/OAuth2UserAgent#overview
回答by Ryan
There are 2 major "gotchas" that none of the existing answers address.
有两个主要的“陷阱”,现有的答案都没有解决。
- Sometimes
InvalidStateException
is a red herring and the true root cause is some other bug. It took me ~12 hours one time to realize that I hadn't added a new field to the$fillable
array in the model. - Unless you disable session state verification(as other answers here seem to want you to do but not everyone will want to do),
$provider->user()
can only be called once per requestbecause the inside of that functioncallshasInvalidState()
, which then removesthe 'state' entry from the session. It took me hours to realize that I happened to be calling$provider->user()
multiple times, when I should have called it just once and saved the result to a variable.
回答by Greegus
Also check access right on your storage/framework/sessions
folder.
还要检查您的storage/framework/sessions
文件夹的访问权限。
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'
).
在我的例子中,由于这个文件夹在新的 Laravel 项目中是空的,它在最初提交到 GIT 存储库时被遗漏了。之后我在生产服务器上手动创建了它,但显然访问权限错误,因此会话驱动程序不可写(设置为 时'file'
)。
回答by Jan Kotas
In my case it was caused by missing parameters in $fillable
array in User
class. When i added all missing parameters, it started to work properly..
在我的情况下,它是由类中$fillable
数组中缺少参数引起的User
。当我添加所有缺少的参数时,它开始正常工作..
回答by makhag
I was only experiencing this error when logging in via mobile web with the facebook app instead of facebook in browser. The facebook app uses the facebook browser after login instead of your current browser, so is unaware of previous state.
我只在使用 facebook 应用程序而不是浏览器中的 facebook 通过移动网络登录时遇到此错误。facebook 应用程序在登录后使用 facebook 浏览器而不是您当前的浏览器,因此不知道以前的状态。
try {
$socialite = Socialite::driver($provider)->user();
} catch (InvalidStateException $e) {
$socialite = Socialite::driver($provider)->stateless()->user();
}
回答by Quan Hoàng
I've got same happen only when I open my web on mobile and open the dialog by facebook application on my phone.
只有当我在手机上打开我的网站并通过手机上的 Facebook 应用程序打开对话框时,才会发生同样的情况。
I think:
This happen because open facebook app to get response from Facebook API make we lost some cookie. it's become stateless.
Then I just use the option that socialite
are already made to avoid stateless
request.
我认为:发生这种情况是因为打开 facebook 应用程序以获取来自 Facebook API 的响应使我们丢失了一些 cookie。它变成了无国籍状态。然后我只是使用socialite
已经做出的选项来避免stateless
请求。
$user = Socialite::driver($provider)->stateless()->user();
It's worked to me. hope it help you
它对我有用。希望对你有帮助
回答by mwallisch
2020/04
2020/04
If this issue appeared for you around Feb. 2020, there is a good chance it has to do with Google Chrome version 80+ which was released in the beginning of Feb. 2020. I am not going to pretend I understand the issue in it's entirety, but in short Google Chrome treats cookies now as SameSite=Lax by default if no SameSite attribute is specified.
如果您在 2020 年 2 月左右出现此问题,则很有可能与 2020 年 2 月初发布的 Google Chrome 80+ 版有关。我不会假装我完全理解该问题,但简而言之,如果没有指定 SameSite 属性,谷歌浏览器现在默认将 cookie 视为 SameSite=Lax 。
If your app depends on working cross-site cookies, you will need to add "SameSite=None; Secure" to your cookies. In Laravel 5.5+ you can achieve that with two changes in the session configuration:
如果您的应用依赖于跨站点 cookie,则您需要在 cookie 中添加“SameSite=None; Secure”。在 Laravel 5.5+ 中,您可以通过对会话配置进行两项更改来实现这一点:
config/session.php
配置/会话.php
'secure' => env('SESSION_SECURE_COOKIE', true), // or set it to true in your .env file
...
...
'same_site' => "none",
The "none" value was apparently not supported in earlier Laravel versions. But it is now, if this produces a weird error check /vendor/symfony/http-foundation/Cookie.php
and make sure there is a SAMESITE_NONE
constant. If it doesn't exist you probably need to upgrade your Laravel version.
早期的 Laravel 版本显然不支持“none”值。但是现在,如果这会产生一个奇怪的错误检查/vendor/symfony/http-foundation/Cookie.php
并确保有一个SAMESITE_NONE
常量。如果它不存在,你可能需要升级你的 Laravel 版本。
Further reading:
进一步阅读:
回答by Marthinus CJ van der Merwe
I had a similar issue, I've got
我有一个类似的问题,我有
InvalidStateException in AbstractProvider.php line 182
in the function?handleProviderCallback()
?when it re-directs back from Facebook login. It seems to be the same as your issue.
在函数中?handleProviderCallback()
?当它从 Facebook 登录重定向回来时。好像和你的问题一样。
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.
此外我发现我的问题发生在我打开我的网站时没有?www
. 当我打开我的网站时?www.mysite.com
?- 没问题。起初我认为我的问题是随机的,直到我得到了线索?Chris Townsend 对问题的回答。
The Solution
解决方案
Go to your www root, check the laravel file?config/session.php
. Check session Session Cookie Domain
. The default configuration is?
转到您的 www 根目录,检查 Laravel 文件?config/session.php
. 检查会话Session Cookie Domain
。默认配置是?
'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
后?php artisan cache:clear
?和?composer dump-autoload
, 我可以从 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.
在完成这些修改后进行测试时,请务必从浏览器中删除您的 cookie。旧的 cookie 仍然会产生问题。