axios interceptor로 token 관리 및 network connection 체크 하기

Posted by Seongkyun Yu on 2022-05-25
Estimated Reading Time 1 Minutes
Words 318 In Total
Viewed Times

interception!

redux-saga 벗어나기

내가 입사하기 이전에 회사에서 사용하던 코드는 api 관련 처리를 전부 redux-saga로 처리하고 있었다.

이렇게 작성할 경우 몇가지 단점이 있다.

  1. 전역으로 사용하지 않는 데이터까지 store에 저장
  2. 1번을 위해 작성해야할 코드가 지나치게 많음

그래서 전역적으로 필요한 데이터가 아닌 경우 redux-saga를 사용하지 않기로 결정하고 리팩토링을 진행했다.

기존 코드는 jwt token을 middleware에서 관리하고 있었다.

정확히 기억은 안나지만 대강 이런 느낌이었는데 더이상 모든 api를 redux-saga로 요청하지 않을 것이라 다른 방법을 찾아야 했다.

그래서 선택한 방법이 axios interceptor다.


axios interceptor

axios interceptor를 이용하면 axios를 이용하여 요청하는 request나 response를 가로채서 작업을 할 수 있다.

예를들어 request를 보낼 때 특정 header를 수정하여 보낸다거나, response 결과를 미리 가져와서 후처리를 해줄 수도 있다.

자세한 정보는 axios 공식문서를 참조하면 된다.

사용방법을 간단히 설명하자면

이렇게 사용할 수 있다.

앞쪽의 axios 대신 axios instance를 대신 사용할 수 있다.

나는 interceptor를 이용하여

  1. request할 때 access token 붙여서 보내기
  2. response 받을 때 401 error일 경우 refresh 시키기

를 진행하려고 한다.


access token 붙이기

1
2
3
4
5
6
7
8
9
10
11
12
const makeAccessTokenSetter =
(localStorage: Storage) => (originRequest: AxiosRequestConfig) => {
const accessToken = localStorage.getItem("access");

originRequest.headers.Authorization = `Bearer ${accessToken}`;

return originRequest;
};

const setAccessToken = makeAccessTokenSetter(localStorage);

axiosInstance.interceptors.request.use(setAccessToken);

axios request시 넘어오는 originRequest를 이용하여 header에 access token을 넣는다.


refresh 처리하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const makeRefreshAccessTokenLogic =
(localStorage: Storage) => async (err: AxiosError) => {
const { config: originRequest, response } = err;
const needRefreshErrors = ["JWT_EXPIRED", "JWT_ERROR"];

if (response === undefined) return Promise.reject(err);
if (response.status !== 401) return Promise.reject(err);
if (needRefreshErrors.includes(response.data) === false)
return Promise.reject(err);
if (localStorage.getItem("access") === null) {
location.replace("/login");

return Promise.reject(err);
}

try {
const { access: newAccessToken } = await getRefreshTk();
localStorage.setItem("access", newAccessToken);

originRequest.headers.Authorization = `Bearer ${newAccessToken}`;

return axios(originRequest);
} catch (error) {
localStorage.removeItem("access");
location.replace("/login");

return Promise.reject(error);
}
};

If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !