henrbu
henrbu

Reputation: 208

Laravel Socialite Google OAuth with Sanctum: Session created but user_id is null after login

I'm building an API-only SPA with Laravel Sanctum and Nuxt3, using cookie-based session authentication. I’ve implemented Google OAuth using Laravel Socialite.

Here’s my current setup for the Google OAuth flow:

public function googleCallback()
{
    $googleUser = Socialite::driver('google')->stateless()->user();

    $user = $this->authRepository->show($googleUser->email);

    if (!$user) {
        $request = (object)[
            'email' => $googleUser->getEmail(),
            'password' => Str::random(40)
        ];

        $user = $this->authService->register($request);
    }

    session()->regenerate();

    Auth::login($user);

    return redirect('http://localhost:3000/auth/callback?authStatus=' . true . '&email=' . urlencode($user->email));
}

public function googleRedirect()
{
    $redirectUrl = Socialite::driver('google')->redirect()->getTargetUrl();
    return response()->json(['redirect_url' => $redirectUrl]);
}

api.php:

 Route::group(['prefix' => 'v2/auth'], function () {
        Route::get('google/callback', [SocialiteController::class, 'googleCallback']);
        Route::get('google/redirect', [SocialiteController::class, 'googleRedirect']);
    });

The flow seems to work: I'm able to get the user's Google profile data and theoretically log them in. However, when checking the sessions table, I notice that a session is created, but the user_id field is null. As a result, my frontend middleware immediately flags the user as unauthorized when calling /api/user. What could be causing user_id to be null in the session, and how can I ensure the user is correctly authenticated for subsequent API requests?

Any insights on how to resolve this would be appreciated!

Upvotes: 1

Views: 338

Answers (2)

henrbu
henrbu

Reputation: 208

I had to shift Socialite endpoints to web.php. When routes are there, it creates a session on redirect. That solves issue

Upvotes: 0

Kithome
Kithome

Reputation: 44

Presuming that you are using React (http://localhost:300), you need to pass the X-XSRF-TOKEN cookie on the header of your request. This will pick the session cookie generate on successful authentication.

axiosInstanceHeaders(multipart: boolean = false) {
    const xsrfToken = CookieServices.get('XSRF-TOKEN')
    const contentType = multipart === true
        ? 'multipart/form-data'
        : 'application/json'

    return {
        headers: {
            'X-XSRF-TOKEN': xsrfToken,
            'Content-Type': contentType,
        }
    }
}

Also don't forget to add the auth:sanctum middleware on your protected routes.

Upvotes: -1

Related Questions