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 |