2022. 11. 24. 22:17ㆍ프로젝트/플랜트하이커 - 식물생활 종합앱
Axios interceptor?
먼저 Axios interceptor은 따로 다운받아서 사용하는 라이브러리가 아니라, axios라는 데이터 페칭 라이브러리를 이용할때 사용할 수 있는 메서드이다.
Axios interceptor을 이용하면 axios가 서버로 request를 보내기 전 혹은 서버의 응답을 받고 .then으로 처리하기전에 응답을 가로채서 요청/응답 전에 필요한 코드를 실행할 수 있는 메서드이다.
Axios Interceptor 사용이유
가장 첫번째 이유는 UX이고, 두번째 이유는 요청의 분리를 통한 코드 가독성 향상, 유지보수 효율 증가이다.
일반적으로 보안을 이유로 accessToken의 유효기간을 정해놓는다. 이렇게 되면 일반적인 사용자 입장에서는 자신도 모르는 사이에 액세스 토큰이 만료되게되고, 액세스 토큰이 만료된경우 로그인을 한 상태에서 행해야하는 작업에서 서버로부터 거부를 받게되고, 로그인을 다시 해야한다.
이대로 둘 경우 사용자는 토큰이 만료될 때마다 로그인을 해야하는 불편을 갖게되므로 UX적인 측면에서 좋지않다.
또 Axios interceptor와 axios instance 메서드를 이용하면 데이터를 페칭하는 과정에서 권한이 필요한 요청과 일반적인 요청을 분리해서 볼 수 있으므로 코드의 유지보수 측면에서 도움이 된다.
사용법
yarn add axios
npm install axios
먼저 자신이 사용하는 패키지 매니저를 이용해 Axios를 다운로드한다
Axios Instance 생성
const BASE_URL = process.env.REACT_APP_BASE_URL
export const axiosPrivate = axios.create({
baseURL: BASE_URL,
headers: { "Content-Type": "application/json" },
withCredentials: true,
});
기본적인 Axios사용법은 이미 숙지하고있다는 가정하에 사용법을 설명해보자면 axios.create라는 명령어를 이용해 axios의 인스턴스를 생성 할 수 있다. 인자로 BaseURL, Header, 쿠키관련 설정 등등 다양한 설정을 개발자의 요구에맞게 설정할 수 있다.
위 코드에서는 axiosPrivate라는 인스턴스를 형성하고, Export하여 로그인 한 사용자만 요청이 가능한 경우 사용하게 했고 컨텐츠 타입과, 쿠키 전송, 기본 URL을 설정했다. BaseURL의 경우, 보안을 위해 환경변수로 숨겨놓는다.
Request Interceptor
axiosPrivate.interceptors.request.use(
config => {
if (config.headers&&config.headers['Authorization']){
config.headers['Authorization'] = `Bearer ${accessToken}`;
}
return config;
}, (error) => Promise.reject(error)
);
axiosPrivate의 경우 위와 같이 사용하여 로컬스토리지 혹은 Context에 저장된 AccessToken을 해더에 저장해서 보내도록 설정할 수 있다.
Request Interceptor
axiosPrivate.interceptors.response.use(
response => response,
async (error) => {
const prevRequest = error?.config;
if (error?.response?.status === 403 && !prevRequest?.sent){
prevRequest.sent = true;
const newAccessToken = await ()=>{
const refresh = async () => {
const response = await axiosPrivate.post("서버의 리프레시토큰 주소",
JSON.stringify({refreshToken:secureLocalStorage.getItem("refreshToken")}));
secureLocalStorage.setItem("accessToken", response.data.accessToken)
return response.data.accessToken;};
return refresh;
};
prevRequest.headers['Authorization'] = `Bearer ${newAccessToken}`;
return axiosPrivate(prevRequest);
}
return Promise.reject(error);
}
);
(위 코드는 보기 지저분하지만 실제 프로젝트에서는 리프레시를 행하는 함수를 따로 만들어서 코드의 가독성을 높혔다.)
제일 중요한 응답의 경우, 위와 같이 사용하여 응답의 상태코드가 403(인가되지않음) 일 경우 우선적으로 로컬스토리지에 저장된 refreshToken을 이용해 AccessToken을 신규 발급받고, 발급받은 토큰을 스토리지에 저장한후, 새로운 토큰을 이용하여 요청을 보내는 형식으로 화면 전환없이 로그인을 유지할 수 있게 하였다.
'프로젝트 > 플랜트하이커 - 식물생활 종합앱' 카테고리의 다른 글
[Refactoring] 끝났다고 끝이 아니다 리팩토링의 시작 - 주석달기 - (0) | 2022.12.20 |
---|---|
[React 이미지 압축전송] 필요 이상으로 큰 이미지를 서버로 넘기지 말자. Browser Image Compression 을 이용한 이미지 압축 후 전송 (1) | 2022.12.08 |
[로컬스토리지 암호화] React Secure Storage를 이용한 로컬스토리지 데이터 암호 (0) | 2022.11.24 |
[MSW] MSW를 이용한 데이터 모킹 (Mock Service Worker) (0) | 2022.11.11 |
[Recoil Protected Route] Recoil을 이용한 라우트 접근권한 설정 (0) | 2022.11.11 |