티스토리 뷰
서버에 데이터를 요청할 때 헤더에 액세스 토큰을 포함하는 경우가 많습니다. 이 때 액세스 토큰이 만료되면 서버에서 401 에러를 응답받게 되는데, 사용자 경험을 고려하면 액세스 토큰이 만료되었을 때 리프레시 토큰으로 새로운 액세스 토큰을 발급받고 다시 서버에 요청하는 것이 좋습니다. 이를 구현하기 위해서는 axios에서 제공하는 interceptors를 사용하여 구현할 수 있습니다.
1. axios 인스턴스 생성
// api 인스턴스 생성
const api = axios.create({
baseURL,
});
2. axios.interceptors.response를 통해 액세스 토큰 재발급 후 재요청
// 응답을 가로채고 처리하는 인터셉터 설정
api.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
// AccessToken이 만료되었을 경우
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
// 새로운 AccessToken을 발급받습니다.
const newAccessToken = await refreshAccessToken();
// 발급받은 AccessToken으로 요청을 다시 시도합니다.
originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
return api(originalRequest);
}
return Promise.reject(error);
}
);
첫 번째 인자는 응답이 성공했을 때, 두 번째 인자는 요청이 실패했을 때 실행됩니다. 401 에러를 응답받으면 액세스 토큰을 재발급받은 후 새로운 액세스 토큰으로 요청을 다시 시도합니다.
또한 요청을 보낼때에도 interceptors 기능을 사용할 수 있습니다.
3. axois.interceptors.request를 통해 headres에 액세스 토큰 설정
// 요청 보낼 때 headers에 accesstoken 추가
api.interceptors.request.use(
(config) => {
const accessToken = getAccessToken();
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
이렇게 설정하면 api 인스턴스를 통한 요청 시마다 헤더에 액세스 토큰이 자동으로 포함되므로, 요청할 때마다 직접 헤더를 설정할 필요가 없습니다.
전체코드
import axios from 'axios';
import {
getAccessToken,
getRefreshToken,
setAccessToken,
setRefreshToken,
} from './cookie';
const baseURL = process.env.REACT_APP_SERVER_URL;
// api 인스턴스 생성
const api = axios.create({
baseURL,
});
// 새로운 AccessToken을 발급받는 함수
const refreshAccessToken = async () => {
const refreshToken = getRefreshToken();
try {
const response = await axios.get(`${baseURL}v1/oauth/refresh-token`, {
headers: {
Authorization: `Bearer ${refreshToken}`,
},
});
const { accessToken: newAccessToken } = response.data.data;
setAccessToken(newAccessToken);
return newAccessToken;
} catch (error) {
console.error(error);
}
};
// 요청 보낼 때 headers에 accesstoken 추가
api.interceptors.request.use(
(config) => {
const accessToken = getAccessToken();
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 응답을 가로채고 처리하는 인터셉터 설정
api.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
// AccessToken이 만료되었을 경우
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
// 새로운 AccessToken을 발급받습니다.
const newAccessToken = await refreshAccessToken();
// 발급받은 AccessToken으로 요청을 다시 시도합니다.
originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
return api(originalRequest);
}
return Promise.reject(error);
}
);
export default api;
사용법
import api from 'utils/axios';
const getGameRoomList = async () => {
try {
const response = await api.get(`v1/gameRoomList`);
console.log(response);
} catch (error) {
console.error(error);
}
};
'React.js' 카테고리의 다른 글
[React.js] React.js에서의 클로저(컴포넌트 상태 관리의 이해) (0) | 2024.05.21 |
---|---|
[React.js] 메모리제이션을 통해 성능 최적화 하기 (0) | 2024.05.20 |
[React.js] React-Query 라이브러리 useQuery 사용해보기 (1) | 2024.05.10 |
[React.js] rc-dock을 사용한 유연한 탭 레이아웃 구현하기 (0) | 2024.03.22 |
[React.js] 커스텀 훅 사용하기 (useInput, useToggle) (0) | 2024.01.17 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- useQuery
- rc-dock
- react.memo
- revalidateTag
- 해시를 사용한 집합과 맵
- eventemitter3
- useState
- useCallback
- Next.js
- 25329
- react-query
- zustand
- js
- revalidatePath
- baekjoon
- React.JS
- sepolia
- React
- react-three-fiber
- RefreshToken
- 9575
- 백준
- NextAuth
- useMemo
- 20551
- 4659
- dynamic routing
- web3
- 24431
- stompjs
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 30 | 31 |
글 보관함