0

I am using facebook as the login of my application. After the user successfully logs in, they are redirected to my user homepage. But when I try to refresh the page after log in it throws an error:

Laravel \ Socialite \ Two \ InvalidStateException No message

This is the code displayed:

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

    $response = $this->getAccessTokenResponse($this->getCode());

    $user = $this->mapUserToObject($this->getUserByToken(
        $token = Arr::get($response, 'access_token')
    ));

    return $user->setToken($token)
                ->setRefreshToken(Arr::get($response, 'refresh_token'))
                ->setExpiresIn(Arr::get($response, 'expires_in'));
}

This is my Controller code:

<?php
 namespace App\Http\Controllers\Auth;

 use Illuminate\Http\Request;
 use App\Http\Controllers\Controller;
 use Socialite;

 class SocialAccountController extends Controller
{
/**
 * Create a new controller instance.
 *
 * @return void
 */
public function __construct()
{
    $this->middleware('guest');
}
/**
 * Redirect the user to the SNS authentication page.
 *
 * @return Response
 */
public function redirectToProvider($provider)
{
    if ($provider !== 'facebook') {
        return abort(404);
    }

    return Socialite::with($provider)->redirect();
}

public function handleProviderCallback(\App\Models\User $accountService, $provider)
 {
    try {
        $user = Socialite::with($provider)->user();
        $create['name'] = $user->getName();
        $create['email'] = $user->getEmail();
        $create['facebook_id'] = $user->getId();

        $user = $accountService->addNew($create);

        return view ('user.home')->withDetails($user)->withService($provider);
    } catch(Exception $e){
        return redirect('/login');
    }
}
}

I have found some answers but is not effective on my side. I'm stuck on this for 2 days now. How can I resolve this?

Eem Jee
  • 1,239
  • 5
  • 30
  • 64

2 Answers2

1

When you get the callback from an OAuth provider (in this case, Facebook) store the data you need into your database and then redirect the user to an account page, or another page that confirms the link was successful.

That callback URL works specifically with credentials that are provided by the OAuth provider. After it is hit the first time those credentials expire and refreshing the page causes the error. By forcefully redirecting the user to another page then they won't be able to refresh and cause the same issue.

Dwight
  • 12,120
  • 6
  • 51
  • 64
  • Thanks for this, but how can I do it? – Eem Jee Feb 07 '19 at 05:04
  • Instead of `return view('user.home')` from the route after successfully authenticating, return a redirect to another endpoint. So it would be something to the effect of `return redirect()->route('home')` depending on the named routes in your app. – Dwight Feb 07 '19 at 05:54
  • How can I return with the details with it? I think your solution is gonna work but I really don't know where to start. So new to this :( . – Eem Jee Feb 07 '19 at 05:59
  • If your call to `addNew` is persisting a new user model record in the database then you could log that user in by doing something like `auth()->login($user)` so that they have a Laravel session. Then you can access the user model with `auth()->user()`. Alternatively, you can put any data in the session manually and access it that way. – Dwight Feb 07 '19 at 23:20
  • If you google `Socialite InvalidStateException` every single answer will tell you to blindly use the `->stateles()` method. This answer is the only one I could find that correctly explains one of the possible causes of why you might get this exception. In this case you'll need to catch the exception and redirect the user properly. – Ben Feb 09 '21 at 21:18
0

Try to refresh the client_secret and run php artisan cache:clear and

composer dump-autoload. It works fine for me.

Eman Emad
  • 77
  • 1
  • 4
  • 13