add front-urban
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
'use client';
|
||||
|
||||
import { useLayoutEffect, useRef } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useUserAuth } from '@/app/context/UserAuth';
|
||||
import apiClient from './apiClient';
|
||||
|
||||
/**
|
||||
* Debe montarse dentro de <UserAuthProvider>.
|
||||
*
|
||||
* - Request interceptor: añade Authorization: Bearer <token> en cada llamada de apiClient.
|
||||
* - Response interceptor: si el backend responde 401, redirige a /unauthorized.
|
||||
*
|
||||
* Usa useLayoutEffect para que los interceptores queden registrados ANTES
|
||||
* de que cualquier useEffect en componentes hijos dispare requests.
|
||||
*/
|
||||
export function AxiosInterceptorProvider({ children }: { children: React.ReactNode }) {
|
||||
const router = useRouter();
|
||||
const { token } = useUserAuth();
|
||||
|
||||
// El ref se inicializa con el token actual en el montaje.
|
||||
// useLayoutEffect lo mantiene sincronizado antes de que corran los useEffect de hijos.
|
||||
const tokenRef = useRef(token);
|
||||
useLayoutEffect(() => {
|
||||
tokenRef.current = token;
|
||||
}, [token]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const requestId = apiClient.interceptors.request.use(config => {
|
||||
if (tokenRef.current) {
|
||||
config.headers.Authorization = `Bearer ${tokenRef.current}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
const responseId = apiClient.interceptors.response.use(
|
||||
response => response,
|
||||
error => {
|
||||
if (error?.response?.status === 401) {
|
||||
router.push('/unauthorized');
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
return () => {
|
||||
apiClient.interceptors.request.eject(requestId);
|
||||
apiClient.interceptors.response.eject(responseId);
|
||||
};
|
||||
}, [router]);
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import axios from 'axios';
|
||||
|
||||
/**
|
||||
* Instancia axios compartida para todas las llamadas al backend.
|
||||
* - baseURL apunta a NEXT_PUBLIC_BACKEND_URL
|
||||
* - El header Authorization se inyecta automáticamente por AxiosInterceptorProvider
|
||||
* cuando el usuario está autenticado.
|
||||
*/
|
||||
const apiClient = axios.create({
|
||||
baseURL: process.env.NEXT_PUBLIC_BACKEND_URL ?? '',
|
||||
});
|
||||
|
||||
export default apiClient;
|
||||
Reference in New Issue
Block a user