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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 21:57:03  来源:igfitidea点击:

Laravel Socialite: InvalidStateException

phpfacebooklaravellaravel-5

提问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

解决方案

  1. Go to your www root, check the laravel file config/session.php
  2. Check session Session Cookie Domain The default configuration is 'domain' => null,I made a change to 'domain' => 'mysite.com'.
  3. After 'php artisan cache:clear'and 'composer dump-autoload', I can login with no issue from both www.mysite.comand mysite.com
  1. 转到您的 www 根目录,检查 Laravel 文件 config/session.php
  2. 检查 session Session Cookie Domain 默认配置是'domain' => null,我对'domain' => 'mysite.com'.
  3. 'php artisan cache:clear'和之后'composer dump-autoload',我可以毫无问题地登录www.mysite.commysite.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 statereturned by a thirdparty service, you can set Socialite to avoid this checking with the statelessmethod:

如果您需要读取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, stateis 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.

有两个主要的“陷阱”,现有的答案都没有解决。

  1. Sometimes InvalidStateExceptionis 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 $fillablearray in the model.
  2. 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 functioncalls hasInvalidState(), 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.
  1. 有时InvalidStateException是一个红鲱鱼,真正的根本原因是其他一些错误。我花了大约 12 个小时才意识到我没有向$fillable模型中的数组添加新字段。
  2. 除非您禁用会话状态验证(因为这里的其他答案似乎希望您这样做但不是每个人都愿意这样做),否则$provider->user()每个请求只能调用一次,因为该函数内部调用hasInvalidState(),然后从中删除“状态”条目会议。我花了几个小时才意识到我碰巧调用了$provider->user()多次,而我应该只调用一次并将结果保存到变量中。

回答by Greegus

Also check access right on your storage/framework/sessionsfolder.

还要检查您的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 $fillablearray in Userclass. 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 socialiteare already made to avoid statelessrequest.

我认为:发生这种情况是因为打开 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.phpand make sure there is a SAMESITE_NONEconstant. 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 仍然会产生问题。