Problema
Estou construindo um aplicativo com um frontend Next.js e um backend Laravel usando Sanctum para autenticação SPA. Quando eu entro no aplicativo Next.js, consigo ver os cookies de autenticação sendo definidos no navegador, mas solicitações subsequentes para obter informações do usuário retornam erros "não autenticados". OBSERVAÇÃO: Tudo está funcionando corretamente no Postman.
Ambiente
- Frontend: Next.js
- Backend: Laravel com Sanctum
- Autenticação: Autenticação Laravel Sanctum SPA
- Tudo funciona corretamente ao testar no Postman
O que eu tentei
O processo de login funciona bem, e posso confirmar que os cookies são definidos no navegador após o login. No entanto, quando tento buscar as informações do usuário autenticado, recebo erros "não autorizado". Tentei a solicitação GET em "/api/v1/user" no Postman e funcionou.
Código
Minha função de login:
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();
};
Buscar função do usuário:
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;
}
};
Eu descobri o problema! O problema estava em
SANCTUM_STATEFUL_DOMAINS="localhost:3000"
. Quando eu executo o backend, ele pega a porta 3000 e meu servidor NEXT está rodando em uma porta diferente (3002) no meu caso. Eu atualizei .env para a porta 3002 e funcionou.