axios interceptors 자체는 토큰 재갱신에서 잠깐 봤지만 그 땐 다른 기능들이 더 급하여 잠시 미루고 useEffect로만 토큰 재갱신을 했었으나
api 통신에서 공통된 헤더를 묶고,
react-query 사용시 페이지에서 직접적으로 api를 사용하고 싶지 않아 (분리하고 싶어서) 다시 연구하던중
axios interceptors로 다시 돌아가게 되어 작업을 하게 되었다.
// import { TokenRefresh } from "api/auth";
import axios from "axios";
import { showToast } from "components/toast/showToast";
import { ROOT_API } from "constants/api";
import store from "store";
import { SET_TOKEN, refreshAccessToken, tokenSlice } from "store/Auth";
const apiInstance = axios.create({
baseURL: "루트 도메인",
headers: {
"Content-Type": "application/json",
},
timeout: 5000,
});
// api를 요청하기전에 실행. axios로 지정한다면 axios요청하기 전에 실행.
apiInstance.interceptors.request.use(
async (config) => {
const accessToken = store.getState().authToken.accessToken;
const refreshToken = localStorage.getItem("dtrtk");
// console.log("인터셉터 토큰", accessToken);
if (accessToken) {
config.headers["X-AUTH-TOKEN"] = `${accessToken}`;
return config;
}
// if (!accessToken && refreshToken) {
// showToast("error", "회원 정보가 만료되었습니다.");
// return config;
// }
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 요청이 완료된후
apiInstance.interceptors.response.use(
(response) => {
// console.log("인터셉터 re", response.data);
// if (response.status === 200) {
// console.log("Request succeeded!");
// }
// if (response.status !== 200) {
// console.log("dd");
// }
const res = response.data;
return res;
},
async function (err) {
if (err.response && err.response.status === 401) {
// 토큰 재발급 요청
const data = await axios.post(`${ROOT_API}/token/refresh`, {
refreshToken: localStorage.getItem("dtrtk"),
headers: {
accept: "*/*",
"Content-Type": "application/json",
},
});
// store 갱신
store.dispatch(
SET_TOKEN({
accessToken: `${data.data.accessToken}`,
})
);
// 헤더에 담긴 토큰 값 변경
err.config.headers = {
"Content-Type": "application/json",
"X-AUTH-TOKEN": `${data.data.accessToken}`,
};
// 재요청
const originalResponse = await axios.request(err.config);
return originalResponse.data;
}
return Promise.reject(err);
}
);
export default apiInstance;
댓글