회사에서 RefreshToken 기반 인증 방식이 도입되면서, 이에 맞춰 axios interceptors를 활용해 토큰 갱신 로직을 구현하게 되었다.
axios 인터셉터란, then 또는 catch로 처리되기 전에 요청(request)과 응답(response)을 가로채어 로직을 삽입할 수 있는 기능이다.
토큰 처리 플로우
interceptors를 통해 다음과 같은 흐름으로 토큰을 관리했다:
요청 또는 응답을 받을 때,
AccessToken이 없거나 만료된 경우,
RefreshToken이 유효하다면, 새로운 AccessToken을 받아오고,
기존 요청(originalRequest)을 다시 시도한다.
즉, 사용자는 만료된 토큰으로 인해 인증 실패를 직접 겪지 않고, 내부적으로 자동 갱신되어 API 요청이 원활하게 처리된다.
const checkRefreshAndAccessToken = async () => {
const hasRefreshToken = await RefreshToken여부 // boolean
const hasAccessToken = await AccessToken여부 // boolean
return { hasRefreshToken, hasAccessToken };
};
axios.interceptors.response.use(
async (response) => {
const { config } = response;
const originalRequest = config;
const { hasRefreshToken, hasAccessToken } = await checkRefreshAndAccessToken();
if (hasRefreshToken && !hasAccessToken) {
await refreshAccessToken();
return axios(originalRequest);
}
return response;
},
async (error) => {
const { config } = error;
const originalRequest = config;
const resp = error.response;
const { hasRefreshToken, hasAccessToken } = await checkRefreshAndAccessToken();
if (resp && resp.status >= 400) {
await refreshAccessToken();
if (!hasRefreshToken && !hasAccessToken) {
// refreshToken, AccessToken 둘 다 없을 경우 처리
}
return axios(originalRequest);
}
return Promise.reject(error);
}
);
정상적인 응답 시에도 체크를 하게 했는데 정책상 에러가 아니어도 토큰이 필요한 경우가 있어서 방어코드를 작성하였다.