skip to Main Content

I’m using Laravel breeze-next nextjs starter package to create a nextjs app with a backend powered by laravel and protected by sanctum.

Laravel expects a csrf header value and a session cookie. I’m having no problem setting these values in client components and getting data back from laravel using something like this:

async function fetchData(url: string): Promise<Response> {
    let fetch_path = process.env.NEXT_PUBLIC_BACKEND_URL + '/api/' + url
    console.log('fetch data called')

    const options: RequestInit = {
        method: "GET",
        credentials: "include",
        headers: {
            "Accept": "application/json",
            "Referer": process.env.APP_URL,
            "X-Requested-With": "XMLHttpRequest",
            "Content-Type": "application/json",
        }
    };

    return await fetch(fetch_path, options);
}

When I try to make an API request in a server component doing something similar it fails every time with a 401:

async function fetchDataServerSide(url: string) {
    'use server'
    let fetch_path = process.env.NEXT_PUBLIC_BACKEND_URL + '/api/' + url

    const options: RequestInit = {
        method: "GET",
        headers: {
            "Accept": "application/json",
            "Referer": process.env.APP_URL,
            "X-Requested-With": "XMLHttpRequest",
            "Content-Type": "application/json",
            "X-CSRF-TOKEN": cookies().get('XSRF-TOKEN'),
        }
    };

    return await fetch(fetch_path, options);
}

Note that this is basically exactly what I’m doing with the same calls via Postman, and they work as expected.

Can anyone point out what I’m doing wrong?

2

Answers


  1. Chosen as BEST ANSWER

    Thanks to @Ahmed for the help, he put me on the right track. The full call I needed to make was the following:

    async function fetchDataServerSide(url: string): Promise<Response> {
        'use server'
        let fetch_path = process.env.NEXT_PUBLIC_BACKEND_URL + '/api/' + url
    
        const options: RequestInit = {
            method: "GET",
            headers: {
                "Accept": "application/json",
                "Referer": process.env.APP_URL,
                "X-Requested-With": "XMLHttpRequest",
                "Content-Type": "application/json",
                "cookie": "XSRF-TOKEN=" + cookies().get('XSRF-TOKEN').value + ";breezeapi_session="+cookies().get('breezeapi_session').value,
            }
        }
    
        return await fetch(fetch_path, options);
    }
    

    When I dumped the request object in the laravel middleware, the cookie header had been converted into an actual cookie array.


  2. Next.js‘s cookies().get(key) doesn’t return the actual value of the cookie. It returns object of {name: string, value: string}.

    async function fetchDataServerSide(url: string) {
        'use server'
        let fetch_path = process.env.NEXT_PUBLIC_BACKEND_URL + '/api/' + url
    
        const options: RequestInit = {
            method: "GET",
            headers: {
                "Accept": "application/json",
                "Referer": process.env.APP_URL,
                "X-Requested-With": "XMLHttpRequest",
                "Content-Type": "application/json",
                "X-CSRF-TOKEN": cookies().get('XSRF-TOKEN').value, // ⬅️⬅️⬅️⬅️
            }
        };
    
        return await fetch(fetch_path, options);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search