import axios from 'axios'; import store from "../../views/pages/AppStore"; // JWT 토큰 디코더 function decodeToken(token) { try { const base64String = token.split('.')[1]; const base64 = base64String.replace(/-/g, '+').replace(/_/g, '/'); const jsonPayload = decodeURIComponent(atob(base64).split('').map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) ).join('')); return JSON.parse(jsonPayload); } catch (e) { console.error("Invalid token", e); return null; } } // 공통 API 클라이언트 const apiClient = axios.create({ baseURL: '/', headers: { 'Content-Type': 'application/json; charset=UTF-8', } }); // 요청 인터셉터 - 토큰이 있으면 Authorization 헤더 추가 apiClient.interceptors.request.use( config => { if (store.state.authorization) { config.headers.Authorization = store.state.authorization; } return config; }, error => Promise.reject(error) ); // 응답 인터셉터 apiClient.interceptors.response.use( response => { return response }, async error => { const originalReq = error.config; if (!error.response) return Promise.reject(error); // 로그인 요청 if (originalReq?.skipAuthRefresh) { return Promise.reject(error); } // 권한 없음 if (error.response.status === 403 && error.response.data.message === '접근 권한이 없습니다.') { window.history.back(); return Promise.reject(error); } // 리프레시 토큰 요청 if (originalReq.url.includes('/refresh/tknReissue.json')) { return Promise.reject(error); } // 토큰 만료 시 한 번만 재시도 if (error.response.status === 401 && !originalReq._retry) { originalReq._retry = true; try { const res = await axios.post('/refresh/tknReissue.json',{}); const newToken = res.headers.authorization; // 토큰 저장 store.commit('setAuthorization', newToken); originalReq.headers.Authorization = store.state.authorization; // 유저 정보 다시 저장 const user = decodeToken(newToken); store.commit("setUserInfo", { userNm: user.userNm, loginId: user.loginId, userId: user.userId, roles: Array.isArray(user.roles) ? user.roles.map(r => r.authority) : [], }); // 실패했던 요청 재시도 return apiClient(originalReq); } catch (refreshError) { // 리프레시 실패 - 세션 만료 처리 sessionStorage.setItem("redirect", window.location.pathname + window.location.search); alert('세션이 종료 되었습니다.\n로그인을 새로 해주세요.'); store.commit("setStoreReset"); localStorage.clear(); sessionStorage.clear(); window.location.href = '/login.page'; return Promise.reject(refreshError); } } return Promise.reject(error); } ); export default apiClient;