Axios.interceptors.request
Axios.interceptors.response
request를 보내는 첫 단계와, response를 받는 첫 단계에서
axios interceptor를 통해 미들웨어처럼 로직 핸들링하기
- access token을 refresh token을 통해 자동으로 갱신하는 로직에 활용
(refresh token 또한 만료시에는 Home으로 redirect)
// src/api.ts
axiosInstance.interceptors.request.use(
(config) => {
const {access_token, refresh_token, access_token_expire_at, refresh_token_expire_at} = store.getState().token;
let accessToken = access_token;
let refreshToken = refresh_token;
if (!access_token_expire_at || !refresh_token_expire_at || !accessToken || !refreshToken) {
return config;
}
if (!config.headers["Authorization"]) {
axiosInstance.defaults.headers.common["Authorization"] = 'Bearer ' + accessToken;
config.headers["Authorization"] = `Bearer ${accessToken}`;
}
return config;
},
(error) => Promise.reject(error)
);
axiosInstance.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
const originalRequest = error.config;
if (error.response.status === 401) {
const refreshToken = store.getState().token.refresh_token;
if (!refreshToken) {
await handleLogoutAndRedirect();
return Promise.reject(error);
}
try {
const response = await refreshAccessToken(refreshToken);
const { access_token } = response;
axiosInstance.defaults.headers.common["Authorization"] = 'Bearer ' + access_token;
originalRequest.headers["Authorization"] = 'Bearer ' + access_token;
store.dispatch(setCredentials(response));
return axiosInstance(originalRequest);
} catch (refreshError) {
await handleLogoutAndRedirect();
}
}
return Promise.reject(error);
}
);
interceptors.request.use
- redux store에 access token이 있는 경우 request header에 토큰 추가하여 request 요청
interceptors.response.use
- 일반 response (에러 없는 경우)
-> 그냥 response return
- 401 error를 반환받은 경우
-> refresh token을 store에서 가져온 후 refresh token을 활용해
access token을 재발급 받는 refreshAccessToken api 사용
-> 정상 진행시
access_token을 global로 사용될 axiosInstance headers에 포함,
오류가 발생했던 request를 다시 한번 request를 진행할 originalRequest의 headers에도 access_token을 포함
store에도 token 정보 저장
-> error가 났던 request를 토큰을 갱신하여 재요청
-> 오류 발생시
Logout과 Redirect 진행 (해당 부분에 대한 상세 로직은 아래 링크 참조)
https://taltal-dev-note.tistory.com/347
* 해당 커밋 내역
https://github.com/Junanjunan/g6_react/commit/d2be1df667903c5720da5097a8540d579aeb3501
https://github.com/Junanjunan/g6_react/commit/c676b570d9b20b2a5a1fb5bbfa669a96798f66e5
https://github.com/Junanjunan/g6_react/commit/4586b0c0ff89ce654c4acd01321b15e99455c300
https://github.com/Junanjunan/g6_react/commit/707f2d4ec8620d1a3072bc0769672511939407be
'React' 카테고리의 다른 글
React: navigation을 Promise의 resolve로 넘겨서 사용하기 (0) | 2024.06.28 |
---|---|
React: Component내의 element를 useRef를 통해 접근 및 값 변경 (0) | 2024.06.20 |
React: React 프로덕션 모드로 localhost 실행 시키기 # strict mode (0) | 2024.06.19 |
React: useForm을 활용해서 다른 컴포넌트 간에 변수 주고 받는 예제 # useForm # watch # useFormContext # 파일 업로드 (0) | 2024.06.18 |
React: Strict mode # useEffect # useRef (0) | 2024.06.13 |