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