then
또는 catch
로 처리되기 전에 요청과 응답을 가로챌수 있습니다.
// 요청 인터셉터 추가하기
axios.interceptors.request.use(function (config) {
// 요청이 전달되기 전에 작업 수행
return config;
}, function (error) {
// 요청 오류가 있는 작업 수행
return Promise.reject(error);
});
// 응답 인터셉터 추가하기
axios.interceptors.response.use(function (response) {
// 2xx 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
// 응답 데이터가 있는 작업 수행
return response;
}, function (error) {
// 2xx 외의 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
// 응답 오류가 있는 작업 수행
return Promise.reject(error);
});
나중에 필요할때 인터셉터를 제거할 수 있습니다.
const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);
커스텀 인스턴스에서도 인터셉터를 추가할 수 있습니다.
const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});
JWT 인증방식 로그인 + 토큰 로컬스토리지에 저장
특정 프로젝트에서 밑과 같이 구현했다.
JWT토큰 전달,갱신방식
전달방식 - headers로 토큰 전달
갱신방식 - Access 토큰이 만료되면 Refresh 토큰을 요청에 같이 전달. 응답으로 갱신된 토큰 받았음.
access토큰 있으면 JWT 디코딩해서 만료시간 검사
만료됐으면 만료된 access + refresh 토큰 같이 헤더에 담아서 요청
만료안됐으면 access만 요청 전 헤더에 담는 작업 수행
access 토큰 만료돼서 응답헤더에 새로운 access토큰이 받아지면
만료된 access토큰 localStorage에서 삭제 후 새 토큰으로 교체
이후 요청 헤더에 새 access토큰을 담기
구현코드
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import { ACCESS_EXP_MESSAGE, CheckJWTExp } from 'utils/CheckJwtExp';
import {
getLocalStorage,
removeLocalStorage,
setLocalStorage,
} from './localStorage';
axios.defaults.withCredentials = true;
/** 1. 요청 전 - access토큰있는데 만료되면 refresh토큰도 헤더담아서 요청보내기 */
axios.interceptors.request.use(
(config: AxiosRequestConfig) => {
const accessToken = getLocalStorage('access_token');
const refreshToken = getLocalStorage('refresh_token');
if (accessToken) {
/** 2. access토큰 있으면 만료됐는지 체크 */
if (CheckJWTExp() === ACCESS_EXP_MESSAGE) {
/** 3. 만료되면 만료된 access, refresh 같이 헤더 담아서 요청 */
config.headers!.Authorization = `${accessToken}`;
config.headers!.Refresh = `${refreshToken}`;
} else {
config.headers!.Authorization = `${accessToken}`;
}
}
return config;
},
(error) => Promise.reject(error)
);
/** 4. 응답 전 - 새 access토큰받으면 갈아끼기 */
axios.interceptors.response.use(
async (response: AxiosResponse) => {
if (response.headers.authorization) {
const newAccessToken = response?.headers?.authorization;
removeLocalStorage('access_token'); // 만료된 access토큰 삭제
setLocalStorage('access_token', newAccessToken); // 새걸로 교체
response.config.headers = {
authorization: `${newAccessToken}`,
};
}
return response;
},
(error) => {
//응답 200 아닌 경우 - 디버깅
return Promise.reject(error);
}
);
참고
- https://velog.io/@hoje15v/react-typescript-Axios-interceptors%EB%A1%9C-%ED%86%A0%ED%81%B0-%EC%97%B0%EC%9E%A5%ED%95%98%EB%8A%94-%EB%B2%95#%F0%9F%A7%90-%ED%94%84%EB%A1%A0%ED%8A%B8-%EC%AA%BD%EC%97%90%EC%84%9C-%ED%86%A0%ED%81%B0%EC%9D%98-%EB%A7%8C%EB%A3%8C%EC%8B%9C%EA%B0%84-%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94-%EB%B2%95
- https://velog.io/@xmun74/axios-interceptors-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0