Laravel Socialite:InvalidStateException

rap*_*2-h 52 php facebook laravel laravel-5

我正在使用Laravel Socialite在网站上添加Facebook连接按钮.有时候,我在回调时遇到了这个错误:

exception 'Laravel\Socialite\Two\InvalidStateException' 
in /example/vendor/laravel/socialite/src/Two/AbstractProvider.php:161
Run Code Online (Sandbox Code Playgroud)

我不知道这是什么意思,也没有发现任何关于这个错误的信息.真正的问题是它似乎是一个随机的例外(不明白它为什么会发生).那么这个错误意味着什么,以及如何避免它?

它似乎与Laravel 5在AbstractProvider.php中引发InvalidStateException的问题不同,因为在我的情况下它是随机的.

小智 77

我昨晚遇到了这个问题并用以下解决方案解决了这个问题.

关于我的问题的更多信息,我有

AbstractProvider.php第182行中的InvalidStateException

handleProviderCallback()从Facebook登录重新定向的功能中.它似乎和你的问题一样.

此外,我发现我的问题发生在我没有打开我的网站时www.当我打开我的网站时www.mysite.com- 没问题.起初我认为我的问题是随机的,直到我得到Chris Townsend回答这个问题的线索- 非常感谢你.

解决方案

  1. 转到www root,检查laravel文件 config/session.php
  2. 检查会话会话Cookie域默认配置是'domain' => null,我对其进行了更改'domain' => 'mysite.com'.
  3. 'php artisan cache:clear''composer dump-autoload',我可以没有从两个问题登录www.mysite.commysite.com

在完成这些修改后测试时,请务必从浏览器中删除Cookie.旧饼干仍然可能产生问题.

  • 正确,但适用于在 localhost 和 Chrome 上工作的人。请记住,Chrome 现在确实为 localhost 设置了 cookie,因此问题仍然存在,以解决将有效的(带点的)域名添加到主机文件,然后相应地更改 Laravel 配置文件的问题。 (2认同)
  • 在localhost的情况下,我应该为域写什么? (2认同)
  • 需要更改 config/session.php 中的“域”和“cookie”值。否则用户会遇到意外的登录问题。请参阅 /sf/ask/2328259951/#35694300 (2认同)
  • 我只是将www重定向到`.htaccess`中的非www.我使用了[本文](https://simonecarletti.com/blog/2016/08/redirect-domain-http-https-www-apache/),它还将HTTP重定向到HTTPS. (2认同)

小智 43

解决 :

Socialite::driver('google')->stateless()->user()
Run Code Online (Sandbox Code Playgroud)

  • 请务必在重定向行中添加“stateless()”,否则重定向后登录可能会遇到问题。`Socialite::driver('google')->stateless()->redirect() ` (4认同)
  • 它有什么作用,为什么需要它? (4认同)
  • 采用“stateless()”并非没有潜在的安全成本。在这里阅读一个不太可能但真实的攻击场景:/sf/answers/2519203011/ 也许这对您和您的用户来说没问题,也许不是。 (2认同)

Igo*_*rra 13

TL;博士

如果需要读取state第三方服务返回的给定参数,可以设置Socialite以避免使用以下stateless方法进行检查:

   Socialite::driver($provider)->stateless();
Run Code Online (Sandbox Code Playgroud)

我认为社交网已经准备好避免这个问题了.

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;
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

例如,state通过谷歌传递数据非常有用:

参数:state(任何字符串)
提供在收到响应时可能对应用程序有用的任何状态.Google授权服务器会对此参数进行往返,因此您的应用程序会收到与其发送的值相同的值.可能的用途包括将用户重定向到站点中的正确资源,以及跨站点请求伪造缓解.

参考:https://developers.google.com/identity/protocols/OAuth2UserAgent#overview


Rya*_*yan 10

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

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


Ous*_*led 9

2020年10月

\n

对我来说,我有

\n
\xe2\x80\xa6\\vendor\\laravel\\socialite\\src\\Two\\AbstractProvider.php209\n
Run Code Online (Sandbox Code Playgroud)\n

所以我将我的代码转换为

\n
$user = Socialite::driver('facebook')->user();\n
Run Code Online (Sandbox Code Playgroud)\n

\n
$user = Socialite::driver('facebook')->stateless()->user();\n
Run Code Online (Sandbox Code Playgroud)\n

我不需要运行任何缓存清除,但我确实删除了cookie,但我不确定你是否必须这样做。

\n

  • 你能解释一下为什么“stateless()”解决了这个问题吗?它也对我有用,但我想知道为什么需要它以及为什么它可以修复它。谢谢。 (4认同)

小智 6

我只在使用 facebook 应用程序而不是浏览器中的 facebook 通过移动网络登录时遇到此错误。facebook 应用程序在登录后使用 facebook 浏览器而不是您当前的浏览器,因此不知道以前的状态。

try {
    $socialite = Socialite::driver($provider)->user();
} catch (InvalidStateException $e) {
    $socialite = Socialite::driver($provider)->stateless()->user();
}
Run Code Online (Sandbox Code Playgroud)


小智 6

仅当我在手机上打开网页并通过手机上的 facebook 应用程序打开对话框时,才会发生同样的情况。

我认为:发生这种情况是因为打开 Facebook 应用程序以获取 Facebook API 的响应使我们丢失了一些 cookie。它变得无国籍了。socialite然后我只是使用已经做出的选项来避免stateless请求。

$user = Socialite::driver($provider)->stateless()->user();
Run Code Online (Sandbox Code Playgroud)

这对我有用。希望对你有帮助


mwa*_*sch 5

2020/04

如果您在 2020 年 2 月左右出现此问题,则很可能与 2020 年 2 月初发布的 Google Chrome 80+ 版本有关。我不会假装我完全理解该问题,但简而言之,如果未指定 SameSite 属性,Google Chrome 现在默认将 cookie 视为 SameSite=Lax。

如果您的应用程序依赖于有效的跨站点 cookie,您需要将“SameSite=None; Secure”添加到您的 cookie 中。在 Laravel 5.5+ 中,您可以通过会话配置中的两个更改来实现这一点:

配置/会话.php

'secure' => env('SESSION_SECURE_COOKIE', true), // or set it to true in your .env file
Run Code Online (Sandbox Code Playgroud)

...

'same_site' => "none",
Run Code Online (Sandbox Code Playgroud)

早期的 Laravel 版本显然不支持“none”值。但现在是这样,如果这会产生奇怪的错误检查/vendor/symfony/http-foundation/Cookie.php并确保有一个SAMESITE_NONE常量。如果它不存在,您可能需要升级 Laravel 版本。

进一步阅读: