mitmitwiki
axios interceptors로 401 error 처리
kohi ☕
2023. 4. 2. 02:16
처리 내용
1. 유저 로그인 시 액세스 토큰과 리프레시 토큰을 발급한다. 액세스 토큰은 클라이언트에서 store 변수에 담아 관리하고 리프레시 토큰은 서버에서 httpOnly 쿠키에 저장하도록 처리한다.
2. API 요청 시 액세스 토큰을 검증한다.
3. 액세스 토큰이 만료된 경우 401 error ▶ token refresh 요청 ▶ 액세스 토큰 발급
4. 새로 발급된 토큰으로 재요청한다.
axios interceptors
axios interceptors는 then이나 catch로 처리되기 전에 요청(request)나 응답(response)을 가로채 어떠한 작업을 수행할 수 있게 한다.
// 요청 쌔벼서 가공
customAxios.interceptors.request.use(
(config) => {
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 응답 쌔벼서 가공
customAxios.interceptors.response.use(
(response) => {
return response;
},
(error) => {
return Promise.reject(error);
}
);
작성한 코드
customAxios.interceptors.response.use(
(response) => {
const res = response.data;
return res;
},
async (error) => {
const err = error as AxiosError;
// 401 error일 때
if (err.response?.status === 401) {
const data = err.response.data;
// 토큰 재발급 요청
const user = store.getState().user;
const { token } = await reissueToken(user.id);
// store 갱신
store.dispatch(
setLogin({
token: `bearer ${token}`,
id: user.id,
account: user.account,
})
);
// 헤더에 담긴 토큰 값 변경
err.config.headers = {
"Content-Type": "application/json",
Authorization: `bearer ${token}`,
};
// 재요청
const originalResponse = await axios.request(error.config);
return originalResponse.data;
// 405 error일 때 (리프레시 토큰 만료)
} else if (err.response?.status === 405) {
alert("로그아웃 되었습니다.");
// store 초기화
store.dispatch(
setLogin({
token: "",
id: 0,
account: null,
})
);
}
return Promise.reject(error);
}
);