Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

yeasirarafat-dev's avatar

Laravel Sanctum SPA authentication

I'm currently working on a Laravel application that consists of two areas: Admin and App. The admin area is built using Inertia.js, and authentication is handled with Sanctum, which is functioning correctly. The app area, on the other hand, utilizes Nuxt 3. My goal is to display content fetched via API from the admin application in the app area. While authentication works well, I encounter a 401 error when attempting to fetch authenticated user data.

Additionally, There is one more issue I'm facing if I'm logged into the admin and trying to login into the app it gives a 305 response on the login request and if I logout from the admin and try to login into the app login is successful but the /api/user response 401 and If I visit the admin area it's showing me authenticated.

The domains for the areas: Admin: admin.kpowa.dev App: app.kpowa.dev:80

.env file in the laravel

SANCTUM_STATEFUL_DOMAINS="app.kpowa.dev,app.kpowa.dev:80,admin.kpowa.dev"
SESSION_DOMAIN=.kpowa.dev

login function

public function store(LoginRequest $request): JsonResponse|RedirectResponse
    {
        // Check if the request is from an SPA
        if (!EnsureFrontendRequestsAreStateful::fromFrontend($request)) {
            // Handle API authentication
            $validated = $request->validated();

            // Ensure rate limiting
            $request->ensureIsNotRateLimited();

            $user = User::query()->where('username', $validated['username'])->first();

            if (!$user || !Hash::check($validated['password'], $user->password)) {
                RateLimiter::hit($request->throttleKey());
                return response()->json(['' => trans('auth.failed')], 422);
            }

            $token = $user->createToken($request->userAgent())->plainTextToken;

            // Clear rate limiter
            RateLimiter::clear($request->throttleKey());

            return response()->json(['token' => $token], 200);
        }

        // Handle SPA authentication
        $credentials = $request->only('username', 'password') + ['type' => 1];
        if (!$request->header('x-inertia')) {
            $credentials = $request->only('email', 'password') + ['type' => [0, 2, 3]];
        }

        try {
            // Attempt authentication
            $request->authenticate($credentials);

            // Authentication successful, regenerate session
            $request->session()->regenerate();

            if (!$request->header('x-inertia')) {
                return response()->json(['status' => trans('auth.login_success')], 200);
            }

            return redirect()->intended(RouteServiceProvider::HOME);
        } catch (\Illuminate\Auth\AuthenticationException | \Illuminate\Validation\ValidationException $e) {
            // Authentication failed, redirect back with error message
            return back()->withErrors(['error' => trans('auth.failed')]);
        }
    }

LoginRequest.php

public function authenticate(array $credentials): void
    {
        $this->ensureIsNotRateLimited();

        if (! Auth::attempt($credentials, $this->boolean('remember'))) {
            RateLimiter::hit($this->throttleKey());

            throw ValidationException::withMessages([
                'error' => trans('auth.failed'),
            ]);
        }

        RateLimiter::clear($this->throttleKey());
    }

Could you assist me in resolving this issue?

0 likes
0 replies

Please or to participate in this conversation.