import axios from "axios"; import { shouldStartLoginRedirect } from "../../../common/core/auth"; import { shouldSuppressDevelopmentSessionRedirect } from "../../../common/core/session"; import { userManager } from "./auth"; let isRedirectingToLogin = false; const apiClient = axios.create({ baseURL: import.meta.env.VITE_DEV_API_BASE ?? import.meta.env.VITE_ADMIN_API_BASE ?? "/api/v1", }); apiClient.interceptors.request.use(async (config) => { // OIDC Access Token 주입 const user = await userManager.getUser(); if (user?.access_token) { config.headers.Authorization = `Bearer ${user.access_token}`; } // TODO: 테넌트 선택 값을 보관하고 헤더로 전달한다. const tenantId = window.localStorage.getItem("dev_tenant_id"); // 키 이름을 좀 더 명확하게 변경 고려 if (tenantId) { config.headers["X-Tenant-ID"] = tenantId; } return config; }); apiClient.interceptors.response.use( (response) => response, async (error) => { const status = error.response?.status; const message = error.response?.data?.error?.toString().toLowerCase() ?? error.response?.data?.message?.toString().toLowerCase() ?? ""; const shouldRedirectToLogin = status === 401 || (status === 403 && (message.includes("authentication required") || message.includes("invalid session") || message.includes("token is not active"))); if (!shouldRedirectToLogin) { return Promise.reject(error); } if ( shouldSuppressDevelopmentSessionRedirect({ appMode: import.meta.env.MODE, }) ) { console.warn( "[apiClient] Auth failure detected, but development session redirects are disabled.", ); return Promise.reject(error); } if ( shouldStartLoginRedirect({ pathname: window.location.pathname, isRedirecting: isRedirectingToLogin, }) ) { isRedirectingToLogin = true; await userManager.removeUser(); window.location.href = "/login"; } return Promise.reject(error); }, ); export default apiClient;