0

Problem

I'm building an application with a Next.js frontend and Laravel backend using Sanctum for SPA authentication. When I login from the Next.js app, I can see the authentication cookies being set in the browser, but subsequent requests to get user information return "unauthenticated" errors. NOTE: Everything is working in Postman correctly.

Environment

  • Frontend: Next.js
  • Backend: Laravel with Sanctum
  • Authentication: Laravel Sanctum SPA Authentication
  • Everything works correctly when testing in Postman

What I've Tried

The login process works fine, and I can confirm cookies are set in the browser after login. However, when I try to fetch the authenticated user information, I get "unauthorized" errors. I tried GET request at "/api/v1/user" in Postman and it works.

Code

My login function:

const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;

async function fetchCsrfCookie() {
    await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/sanctum/csrf-cookie`, {
        method: 'GET',
        credentials: 'include',
    });
}
export const fetchSignIn = async (username: string, password: string) => {
    //   1) Init Sanctum
    await fetchCsrfCookie();

    // 2) Login
    const res = await fetch(`${baseUrl}/api/v1/login`, {
        method: 'POST',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ username, password, remember: true }),
    });
    if (!res.ok) {
        throw new Error('Login failed');
    }
    return res.json();
};

Fetch user function:

export const fetchAuthUser = async () => {
    try {
        const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/v1/user`, {
            method: 'GET',
            credentials: 'include',
            headers: {
                'Content-Type': 'application/json',
            },
        });

        if (!res.ok) {
            const errorData: any = await res.json();
            console.error('Error data:', errorData);
            throw new Error(errorData.message || res.statusText);
        }

        return res.json();
    } catch (error) {
        console.error(`Failed to fetch resource:`, error);
        throw error;
    }
};
8
  • Sorry, can you share your laravel side's .env? I would like to see your session configurations. Please do remove any secret env value such as db password. Commented Apr 2 at 3:54
  • in your fetchAuthUser fetch, unless you are explicitly set in your fetch that you added your JWT token, then it will not include it when submitting the request. Commented Apr 2 at 7:12
  • SESSION_DRIVER=redis SESSION_LIFETIME=120 SESSION_ENCRYPT=true SESSION_PATH=/ SESSION_DOMAIN="localhost" SESSION_SECURE_COOKIE=false SANCTUM_STATEFUL_DOMAINS="localhost:3000" @Tatachiblob Commented Apr 4 at 4:01
  • Thanks, can you try to change this env variable? SESSION_DOMAIN=null Commented Apr 4 at 4:05
  • 1
    @Tatachiblob I just found a solution. Problem was in SANCTUM_STATEFUL_DOMAINS="localhost:3000" . Next is runned at port localhost 3000 by default, but when i start backend, port 3000 is taken and Next is running at different port( 3002 ) in my case. I updated the .env and it works. Thank you. Commented Apr 4 at 4:16

1 Answer 1

0

I figured out the issue! The problem was in SANCTUM_STATEFUL_DOMAINS="localhost:3000" . When I run backend it takes 3000 port and my NEXT server is running at different port(3002) in my case. I updated .env to 3002 port and it worked.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.