
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import axios from 'axios';
import store from "../../views/pages/AppStore";
// 토큰 재발급 함수 (공통 함수로 분리)
const refreshToken = async () => {
const res = await axios.post("/refresh/tknReissue.json", {}, {
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
});
if (res.status === 200) {
console.log("토큰 재발급 성공! 굿~");
// 새로 발급 받은 AccessToken 저장
store.commit('setAuthorization', res.headers.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("setUserNm", mbr.userNm); // 사용자 이름 저장
store.commit('setRoles', mbr.roles); // 사용자 역할 저장
return true;
}
throw new Error("토큰 재발급 요청 실패");
};
// Axios 클라이언트 생성 함수
const createClient = (contentType) => {
const client = axios.create({
headers: {
'Content-Type': contentType,
}
});
// 요청 인터셉터
client.interceptors.request.use(
config => {
const token = store.state.authorization; // Access Token 가져오기
if (token) {
config.headers.Authorization = token; // 토큰 추가
}
return config;
},
error => {
return Promise.reject(error);
}
);
// 응답 인터셉터
client.interceptors.response.use(
response => {
return response;
},
async error => {
const originalReq = error.config;
// 403 에러 처리
if (error.response && error.response.status === 403) {
alert('접근 권한이 없습니다.');
window.history.back();
return Promise.reject(error);
}
// 401 에러 처리 (토큰 만료)
if (error.response &&
error.response.status === 401 &&
error.response.data.message === '로그인 시간이 만료되었습니다.' &&
!originalReq._retry) {
originalReq._retry = true; // 재시도 플래그 설정
try {
// 공통 토큰 재발급 함수 호출
await refreshToken();
// 중요: Content-Type 헤더 보존
originalReq.headers.Authorization = store.state.authorization;
// multipart/form-data 요청의 경우 data 처리 방식이 다름
if (originalReq.headers['Content-Type'] &&
originalReq.headers['Content-Type'].includes('multipart/form-data')) {
// multipart의 경우 FormData가 이미 생성되어 있으므로 그대로 사용
// 특별한 처리 없이 원래 요청 재시도
}
// 원래 요청 재시도
return client(originalReq);
} catch (refreshError) {
const redirect = window.location.pathname + window.location.search;
sessionStorage.setItem("redirect", redirect);
alert('세션이 종료되었습니다.\n로그인을 새로 해주세요.');
store.commit("setStoreReset");
window.location = '/login.page'; // 로그인 페이지로 리다이렉트
return Promise.reject(refreshError);
}
}
return Promise.reject(error);
}
);
return client;
};
// JSON 요청을 위한 apiClient
const apiClient = createClient('application/json; charset=UTF-8');
// 멀티파트 파일 업로드를 위한 fileClient
const fileClient = createClient('multipart/form-data');
export { apiClient, fileClient }; // 두 클라이언트를 내보냄