Laravel 5在AbstractProvider.php中创建InvalidStateException

时间:2015-04-14 13:55:03

标签: php facebook laravel laravel-5

我正在使用社交场所 laravel 5 中使用facebook登录。

这是我的路线文件代码。

Route::get('fb', function ($facebook = "facebook")
{
    $provider = \Socialize::with($facebook);      
    if (Input::has('code'))
    {
        $user = $provider->user();
        return var_dump($user);
    } else {
        return $provider->scopes(['public_profile','user_friends'])->redirect();
    }
});

登录成功,我得到了代码,但get $provider->user()的时间我收到了错误。

  

AbstractProvider.php第161行中的InvalidStateException

11 个答案:

答案 0 :(得分:11)

http://nhagiaodich.com/dang-nhap

它可以在我的网站上运行,只需在获取用户

之前调用 - > gt; stateless()
Socialite::driver('facebook')->stateless()->user()
Socialite::driver('google')->stateless()->user()

答案 1 :(得分:10)

我只是评论出发出错误的代码(如在@Dipesh Shihora的回答中),我感到很不舒服,所以我进一步挖了一下。我发现错误是由于会话问题引起的(至少在我的情况下)。

我的开发服务器是根据this answer中给出的说明设置的。基本上,我通过使用看似公共可访问地址的回调网址“欺骗”Google。

InvalidStateException问题出现在我面前,因为我正在http://localhost/login访问我的登录页面并重定向到Google的登录页面,然后返回http://myapp.example.com/callback。问题是会话密钥存储在cookie中 - 它最初是http://localhost的cookie,但是当我重定向到不同的URL时,cookie(以及会话密钥)无法访问。因此,更新后会话state值不存在,并抛出异常。

解决方案?确保我在开发计算机上的所有浏览都是在http://myapp.example.com而不是http://localhost完成的。

答案 2 :(得分:3)

尝试在'domain'的{​​{1}}字段和config/session.php的{​​{1}}字段中设置正确的值。这对我来说似乎已经成功了。我注意到'url'中的值应该没有config/app.php,而session.php中的值应该是http://

另外,我建议您按照本指南操作:https://laracasts.com/series/whats-new-in-laravel-5/episodes/9。这非常有帮助和明确。

答案 3 :(得分:2)

$provider = \Socialize::with($facebook);      
if (Input::has('code'))     {
    $user = $provider->stateless()->user();
}

也许这是更好的临时解决方案

答案 4 :(得分:1)

所以在做了一些挖掘之后,如果发现我的问题是我的nginx配置错误并且url参数(代码和状态)没有正确传递给index.php文件,这样就检查了状态来自会话和来自网址的状态失败了。 我修改了我的nginx conf看起来像这样,它工作正常。

location / {
            try_files $uri $uri/ /index.php?$args;
    }

答案 5 :(得分:1)

对于遇到这些问题的任何人,您可以将config / session.php中的域值设置为您的域,并清除浏览器中与您的应用网址相关的所有Cookie。你也可以运行php artisan cache:clear and clear-complied

答案 6 :(得分:0)

您收到此错误是因为您的配置文件中的社交提供程序设置有误或无法正确设置您的Facebook应用程序。

访问developers.facebook.com并确保您的应用ID和密钥正确并指向正确的网址。然后确保您的laravel应用程序的services.php配置文件使用正确的重定向,ID和密码进行更新。

答案 7 :(得分:0)

我知道这篇文章有些旧,但是我一直在寻找可能的答案时点击它。

我有同样的错误,但是我的解决方法有所不同。

我在Ubuntu 18.04桌面上进行开发,因为它是带有GUI的服务器。 Socialite在本地运行良好,但是当我通过git将更改推/拉到服务器时,它就退出了。

我通过记录发送给Google和来自Google的内容来运行跟踪。在Socialite有机会获取信息之前,我“ dd($ _ GET)”进行了原始转储,因此我知道存储了什么并可以使用。所有信息都在那里,但是Socialite似乎没有“看到”它。那就是我认为这是我的apache2标头配置干扰了cookie /会话数据。

我在apache2配置中设置了标头安全性。设置之一是

Header always edit Set-Cookie ^(.*) "$1;HttpOnly;Secure;SameSite=Strict"

此设置干扰了社交名流所需的Cookie信息。我从apache2标头配置中删除了该设置(通过注释掉),然后重新启动了Apache。最后,为了确定,我删除了storage / framework / session / *中的所有会话,并从浏览器中清除了它们。那对我有用。

在我开始工作之后,一个接一个地启用并测试了以下每个设置,以使框架安全地保护其可以提供的头信息:

SESSION_SECURE_COOKIE=true

在我的.env文件中

'http_only' => true,'same_site' => 'lax'(设置为“严格”似乎无效)
在我的config / session.php文件中。

现在,它又回到了测试安全性并在需要时进行调整。

答案 8 :(得分:0)

请确保将带有url参数(代码和状态)的查询字符串传递给fpm / mod_php:

# AbstractProvider.php, line 242
...
protected function hasInvalidState()
{
    if ($this->isStateless()) {
        return false;
    }
    --> dd($this->request); <--
    $state = $this->request->session()->pull('state');

    return ! (strlen($state) > 0 && $this->request->input('state') === $state);
}
...

在下面找到一个Nginx配置示例,该示例将$args变量代理到应用程序:

# example.com.conf
location / {
    try_files $uri $uri/ /index.php?$args;
}

确保在QUERY_STRING文件中设置了参数fastcgi_params

# /etc/nginx/includes/fastcgi_params
...
fastcgi_param QUERY_STRING          $args;
...

# example.com.conf
location ~ \.php$ {
    fastcgi_pass fpm:9000;
    fastcgi_index index.php;
    ...
    include /etc/nginx/includes/fastcgi_params;
    ...
}

答案 9 :(得分:-1)

转到 vendor/guzzlehttp/guzzle/src/Client.php

$defaults = [
            'allow_redirects' => RedirectMiddleware::$defaultSettings,
            'http_errors'     => true,
            'decode_content'  => true,
            'verify'          => true,
            'cookies'         => false
        ];

更改为

$defaults = [
            'allow_redirects' => RedirectMiddleware::$defaultSettings,
            'http_errors'     => true,
            'decode_content'  => true,
            'verify'          => **false**,
            'cookies'         => false
        ];

答案 10 :(得分:-5)

我得到了临时解决方案。

public function user()
{
    //if ($this->hasInvalidState()) {
    //    throw new InvalidStateException;
    //}

    $user = $this->mapUserToObject($this->getUserByToken(
        $token = $this->getAccessToken($this->getCode())
    ));
    return $user->setToken($token);
}

评论 AbstractProvider.php 文件中的$this->hasInvalidState() if条件,并且它可以正常工作。