8

I am trying to use login with facebook in laravel 5 using Socialize.

Here is my route file code.

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();
    }
});

login is success and I get the code but time of get $provider->user() I get the error.

InvalidStateException in AbstractProvider.php line 161

Dipesh Shihora
  • 414
  • 2
  • 6
  • 19

12 Answers12

15

I wasn't comfortable with just commenting out code that signalled an error (as in @Dipesh Shihora's answer), so I dug a little further. I discovered that the error is caused (in my case at least) by a problem with sessions.

My dev server is set up according to the instructions given in this answer. Basically, I am "spoofing" Google by using a callback URL which looks like a publicly-accessible address.

The InvalidStateException problem was appearing for me because I was visiting my login page at http://localhost/login and redirecting to Google's login page, which then returned me to http://myapp.example.com/callback. The problem is that the session key is stored in a cookie - it was originally a cookie for http://localhost, but when I redirected to a different URL, the cookie (and hence the session key) was inaccessible. Thus, the session state value was non-existent after the update and the exception was thrown.

The solution? Ensure that all my browsing on the dev machine was done at http://myapp.example.com and not at http://localhost.

Community
  • 1
  • 1
Kryten
  • 15,230
  • 6
  • 45
  • 68
14

http://nhagiaodich.com/dang-nhap

It work on my website , just call ->stateless() before get user

Socialite::driver('facebook')->stateless()->user()
Socialite::driver('google')->stateless()->user()
Nguyen Phuong
  • 1,211
  • 1
  • 10
  • 6
5

Try setting the correct values in the 'domain' field of config/session.php and the 'url' field of the config/app.php. This seems to have done the trick for me. I noted that the value in session.php should be without http://, while the one in app.php should be with http://.

Also, I recommend you follow this guide: https://laracasts.com/series/whats-new-in-laravel-5/episodes/9. It's extremely helpful and clear.

Mattias
  • 1,111
  • 1
  • 14
  • 23
  • 1
    Thanks. Setting the `domain` field worked for me. Never imagined this to be the cause of the error. – igs013 Nov 06 '15 at 14:33
  • Neat! Feel free to mark the answer as correct, as it fixes the issue rather than commenting it out :) Could help people encountering the same problem. – Mattias Nov 06 '15 at 14:36
  • True. The only issue here is that I'm not the one who posted this question so it could be kinda hard for me to mark the answer as correct :)). But nonetheless I've voted up your answer before commenting on it :p. – igs013 Nov 08 '15 at 11:07
  • `domain` was the trouble maker – Edmund Sulzanok Apr 26 '16 at 11:29
2

So after doing some digging if found that the issue for me was that my nginx configuration was wrong and the url parameters (code and state) weren't passed to the index.php file properly and this way the check between the state from the session and the state from the url was failing. I modified my nginx conf to look like this and it worked fine.

location / {
            try_files $uri $uri/ /index.php?$args;
    }
Noki
  • 451
  • 3
  • 6
2
$provider = \Socialize::with($facebook);      
if (Input::has('code'))     {
    $user = $provider->stateless()->user();
}

Maybe this is better temporary solution

DamneD
  • 217
  • 2
  • 5
  • it worked for me, but question is why $provider->stateless()->user()? instead of $provider->user()? – loki9 Sep 03 '15 at 03:42
1

I don't know if this will help anyone but changing my session driver from file to cookie solved the InvalidException issue for me.

Jared Eitnier
  • 7,012
  • 12
  • 68
  • 123
  • This might have been inadvertent, in that you cleared the sessions by doing so, which can cause the state to mismatch (e.g. if the session was generated with a different dev url). – Elliot Sep 02 '23 at 09:25
1

For anyone experiencing these problem, you can set the domain value in config/session.php to your domain and clear all cookies in your browser relating to your app url. you can also then run php artisan cache:clear and clear-complied

valmayaki
  • 191
  • 1
  • 5
1

I know this post is a little old but I kept hitting it while searching for a possible answer.

I had the same error but my solution was a little different.

I develop on Ubuntu 18.04 desktop since it is a server with a GUI. Socialite works great locally but as soon as I pushed/pulled the changes through git to the server, it quit.

I was running traces by recording what was sent to and from google. I "dd($_GET)" to get a raw dump before Socialite had a chance to get the info so I knew what was stored and ready for use. All info was there but Socialite didn't seem to "see" it. That is when I reasoned it was my apache2 header configuration interfering with the cookies/session data.

I had set header security in my apache2 configs. One of the settings was

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

This setting was interfering with the cookie information that socialite needed. I removed that setting from my apache2 header config(by commenting out) and restarted Apache. Finally I removed all sessions in storage/framework/session/* and cleared them from my browser just to be sure. That worked for me.

After I got it working, one by one enabled and tested each of the following settings to have the framework secure what header info it can:

SESSION_SECURE_COOKIE=true

in my .env file

'http_only' => true, and 'same_site' => 'lax'(setting to "strict" did not seem to work)
in my config/session.php file.

Now it is back to testing security and tweaking things back if need be.

Stephen
  • 11
  • 1
  • You're right 'same_site' => 'strict' doesn't work, I'm not sure why, since it is the laravel itself that overwrites the session, there must be a way around this. – Macedo_Montalvão Nov 08 '20 at 13:05
0

you get this error because you have your social provider settings wrong in your config file or haven't set up your Facebook app properly.

Visit developers.facebook.com and make sure your app id and secret keys are correct and pointing to the correct URL. Then make sure your laravel app's services.php config file is updated with the correct redirect, id and secret.

Richard Torcato
  • 2,504
  • 25
  • 26
0

Make sure, that a query string with url parameters (code and state) are passed to the 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);
}
...

Find an example of nginx configuration below, that proxies $args variable to the application:

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

Make sure, that parameter QUERY_STRING is set in fastcgi_params file:

# /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;
    ...
}
antonbormotov
  • 1,821
  • 2
  • 20
  • 32
-1

Go to vendor/guzzlehttp/guzzle/src/Client.php

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

change to

$defaults = [
            'allow_redirects' => RedirectMiddleware::$defaultSettings,
            'http_errors'     => true,
            'decode_content'  => true,
            'verify'          => **false**,
            'cookies'         => false
        ];
Shahzad Barkati
  • 2,532
  • 6
  • 25
  • 33
-7

I got temporary solution for that.

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

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

comment the $this->hasInvalidState() if condition in AbstractProvider.php file and it's work fine.

Pragnesh Rupapara
  • 782
  • 1
  • 12
  • 30
Dipesh Shihora
  • 414
  • 2
  • 6
  • 19
  • Worked for me. Is there a better solution ? – Corentin Jun 04 '15 at 14:10
  • 3
    You should never comment out the code that gives you an error, you should fix the error instead. Downvoted. – Mattias Oct 03 '15 at 16:47
  • @Mattias so can you give me solution for that ? – Dipesh Shihora Oct 05 '15 at 07:28
  • @DipeshShihora I haven't had the time to find a final working solution yet, no. I have found a few clues though, for example setting your Session Cookie Domain and then clearing the application cache, or injecting the Request class into the handleProviderCallback like this: handleProviderCallback(Illuminate\Http\Request $request). But like I said, I haven't tried any of these methods yet. – Mattias Oct 05 '15 at 07:33
  • 1
    @Mattias give me specific reason when you get time then update here so my knowledge also updated and get proper solution for that – Dipesh Shihora Oct 05 '15 at 10:26
  • @DipeshShihora See my answer. – Mattias Oct 05 '15 at 16:33
  • I have this problem on the smartphone but not on desktop. Thank you. Fast trick. – dlopezgonzalez Mar 17 '16 at 12:26