Search code examples
javascriptreactjslaravelnext.jslaravel-breeze

Passing auth credentials in nextjs server side api call


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?


Solution

  • 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);
    }