Axios Interceptor를 이용한 JWT 관리

2025. 1. 8. 01:15프로젝트

axios가 제공하는 interceptor는 HTTP 요청이나 응답이 처리되기 전에 가로채서 특정 로직을 먼저 실행할 수 있도록 해줍니다.

이를 통해서 공통된 처리 로직을 모듈화하거나 자동화할 수 있습니다.

 

https://axios-http.com/kr/docs/interceptors

 

인터셉터 | Axios Docs

인터셉터 then 또는 catch로 처리되기 전에 요청과 응답을 가로챌수 있습니다. axios.interceptors.request.use(function (config) { return config; }, function (error) { return Promise.reject(error); }); axios.interceptors.response.use(f

axios-http.com

해당 페이지에서 어떻게 구현하는지를 확인할 수 있습니다.

 

이번에는 개인프로젝트를 진행하면서 인터셉터를 이용해 요청과 응답에서 JWT 토큰 (Access Token, Refresh Token)에 대한

처리를 어떻게 했는지에 대해서 포스팅하겠습니다.

 

 

 


요청에서 JWT의 처리 흐름

1. 요청 ⇒ 200 정상 요청

요청 후 200코드를 받아서 정상적으로 요청이 성공했을 때는 그대로 응답을 돌려주면 되기 때문에 특별하게 설정할 것이 없습니다.

 

2. 요청 토큰만료 리프레시 토큰으로 갱신요청 200 엑세스 토큰 갱신 후 정상 요청

이 경우는 Access Token만 만료되거나 잘못된 경우입니다.

이 때는 Refresh Token으로 Access Token을 다시 발급받아주는 처리를 하면 됩니다.

 

3. 요청 ⇒ 토큰만료 ⇒ 리프레시 토큰으로 갱신요청 ⇒ 만료 또는 인증정보 에러 ⇒ 로그아웃

마지막으로는 Refresh Token도 만료되거나 인증이 되지않는 경우입니다.

이 경우에는 로그아웃된 상태와 동일하므로 로그인 페이지로 이동시켜줍니다.

 

 

 


interceptor를 이용한 코드 구현

import axios from "axios";
const instance = axios.create();

// 요청 인터셉터
instance.interceptors.request.use((config) => {
    const token = localStorage.getItem('accessToken');
    if(token != null) {
        config.headers["Authorization"] = token;
    }

    return config;
}, (error) => Promise.reject(error));

// 응답 인터셉터
instance.interceptors.response.use((response) => response, async (error) => {
    const originalRequest = error.config;
    const errorCode = error.response?.data?.code;

    if ((errorCode === 'AUTH-001' || errorCode === 'AUTH-002'
        || errorCode === 'AUTH-003' || errorCode === 'AUTH-004')
        && !originalRequest._retry) {

        originalRequest._retry = true;
        try {
            const refreshResponse = await axios.post("auth/refresh", {}, { withCredentials: true });
            const newAccessToken = refreshResponse.headers.authorization;
            localStorage.setItem('accessToken', newAccessToken);

            // 실패했던 요청 다시 시도
            originalRequest.headers["Authorization"] = newAccessToken;
            return instance(originalRequest);
        } catch (refreshError) {
            localStorage.removeItem("accessToken");
            window.location.href = "/login"; // 로그인 페이지로 이동
            return Promise.reject(refreshError);
        }
    }
    return Promise.reject(error);
});
export default instance;

 

주의할 점은 모든 응답에 대해서 검증을하므로 HttpStatus로 판별해서 토큰 갱신을 요청하면 로그인과 같은 요청에서는 원하는대로 동작하지 않기 때문에 백엔드에서는 커스텀 에러를 만들어서 던져주는 방식으로 설정한 후 정의된 error code로 판별해서

토큰 갱신을 요청합니다.

 

커스텀 에러에 대한 내용은 여기에 정리했습니다.

'프로젝트' 카테고리의 다른 글

[React] PrivateRoute 구현  (0) 2025.02.21
Redis를 이용한 휴대폰번호 인증 구현  (0) 2024.12.27