
File name
Commit message
Commit date
05-22
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import axios from 'axios';
import { getGlobalStore } from '../../views/pages/AppStore';
const apiClient = axios.create({
baseURL: '/',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
withCredentials: true // 세션 쿠키를 위해 추가
});
const excludeCtxUrls = [
'/sys/cntxtPth/findLatestCntxtPth.json' // Context Path 정보 호출
, '/sys/loginPolicy/getLoginMode.json' // 로그인 모드 정보 호출
, '/sys/loginPolicy/findByStorageMode.json' // 스토리지 모드 정보 호출
]
apiClient.interceptors.request.use(
config => {
const store = getGlobalStore();
const excludeCtxUrl = excludeCtxUrls.some(url => config.url.includes(url));
const contextPath = store?.state.contextPath || '';
const loginMode = store?.state.loginMode || 'J'; // 기본값은 JWT 모드
if(!excludeCtxUrl) {
config.url = contextPath + config.url;
}
// 로그인 모드에 따른 헤더 설정
if (loginMode === 'J') {
config.headers.Authorization = store?.state.authorization;
} else if (loginMode === 'S') {
delete config.headers.Authorization;
config.withCredentials = true;
}
return config;
},
error => {
return Promise.reject(error);
}
)
apiClient.interceptors.response.use(
response => {
return response;
},
async error => {
if (!error.response) {
return Promise.reject(error);
}
if (error.response.status == 403 && error.response.data.message == '접근 권한이 없습니다.') {
window.history.back();
}
const originalReq = error.config;
const store = getGlobalStore();
const loginMode = store?.state.loginMode || 'J';
if (originalReq.url.includes('/refresh/tokenReissue.json')) {
return Promise.reject(error);
}
// 핵심: 401 에러 처리를 로그인 모드별로 분기
if (error.response.status === 401 &&
error.response.data?.message?.toLowerCase().includes('expired') &&
!originalReq._retry) {
originalReq._retry = true;
if (loginMode === 'J') {
// JWT 모드: 기존 토큰 재발급 로직
try {
const res = await axios.post('/refresh/tokenReissue.json', {}, {
withCredentials: true
});
store.commit('setAuthorization', res.headers.authorization);
originalReq.headers.Authorization = store.state.authorization;
/** jwt토큰 디코딩 **/
const base64String = store.state.authorization.split('.')[1];
const base64 = base64String.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(atob(base64).split('').map(c => {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
const mbr = JSON.parse(jsonPayload);
store.commit("setMbrNm", mbr.mbrNm);
store.commit('setRoles', mbr.roles);
/** jwt토큰 디코딩 끝 **/
return apiClient(originalReq);
} catch (refreshError) {
handleSessionExpired(store);
return Promise.reject(refreshError);
}
} else if (loginMode === 'S') {
// 세션 모드: 토큰 재발급 시도하지 않고 바로 로그인 페이지로
handleSessionExpired(store, '세션이 만료되었습니다.');
return Promise.reject(error);
}
}
return Promise.reject(error);
}
)
// 세션 만료 처리 함수
function handleSessionExpired(store, message = '세션이 종료되었습니다.') {
const redirect = window.location.pathname + window.location.search;
sessionStorage.setItem("redirect", redirect);
alert(`${message}\n로그인을 새로 해주세요.`);
store.commit("setStoreReset");
const admPath = store.state.path?.includes("/adm");
const contextPath = store.state.contextPath || '';
const loginUrl = admPath ? contextPath + "/cmslogin.page" : contextPath + "/login.page";
window.location = loginUrl;
}
export default apiClient;