axios의 인터셉터를 이용하여
엑세스토큰이 만료 되었을 경우 각 함수마다 처리하는게 아닌 공통으로
리프레쉬토큰을 재발급 받아 다시 함수를 처리 하는 방법을 설명하도록 하겠다.
인터셉터란?
then이나catch로 처리되기 전에 요청이나 응답을 가로채는 것 이다.
전체 코드는 다음과 같다.
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
32
33
34
35
36
37
38
39
40
41
|
import axios from 'axios';
import GLOBALS from 'src/common/globals';
const axiosApiInstance = axios.create();
//Request interceptor for API calls
axiosApiInstance.interceptors.request.use(
async config => {
const userInfo = window.sessionStorage.getItem('userInfo');
const accessToken = userInfo ? JSON.parse(userInfo).accessToken : null;
config.headers = {
'Authorization': `Bearer ${accessToken}`,
'Accept': 'application/json',
}
return config;
},
error => {
Promise.reject(error)
});
// Response interceptor for API calls
axiosApiInstance.interceptors.response.use((response) => {
return response
}, async function (error) {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
console.log('토큰 만료')
originalRequest._retry = true;
const sessionObj = window.sessionStorage.getItem('userInfo');
let userInfo = sessionObj ? JSON.parse(sessionObj) : null;
const access_token = await refreshAccessToken(userInfo.refreshToken);
if(userInfo){
originalRequest.headers['Authorization'] = 'Bearer ' + access_token;
userInfo.accessToken = access_token;
window.sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
}
return axios(originalRequest);
}
return Promise.reject(error);
});
|
cs |
1. 인터셉터를 사용할 axios 인스턴스를 생성을 한다.
1
2
3
4
5
|
import axios from 'axios';
import GLOBALS from 'src/common/globals';
const axiosApiInstance = axios.create();
|
cs |
2. 생성한 axios 인스턴스에서 요청을 할때 공통으로 선언한 설정부분.
나는 세션 스토리지에 accessToken을 담았다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
axiosApiInstance.interceptors.request.use(
async config => {
const userInfo = window.sessionStorage.getItem('userInfo');
const accessToken = userInfo ? JSON.parse(userInfo).accessToken : null;
config.headers = {
'Authorization': `Bearer ${accessToken}`,
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
}
return config;
},
error => {
Promise.reject(error)
});
|
cs |
3. 앞에서 생성한 axios 인스턴스에서 인터셉터를 걸어 리프레쉬 토큰 제발급
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// Response interceptor for API calls
axiosApiInstance.interceptors.response.use((response) => {
return response
}, async function (error) {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
console.log('토큰 만료')
originalRequest._retry = true;
const sessionObj = window.sessionStorage.getItem('userInfo');
let userInfo = sessionObj ? JSON.parse(sessionObj) : null;
const access_token = await refreshAccessToken(userInfo.refreshToken);
if(userInfo){
originalRequest.headers['Authorization'] = 'Bearer ' + access_token;
userInfo.accessToken = access_token;
window.sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
}
return axios(originalRequest);
}
return Promise.reject(error);
});
|
cs |
6줄: 만약 에러 발생 시 error객체 안의 responese.status를 이용하여
에러의 내용을 확인하여 상황에 맞게 처리 할 수 있게 하였다
401처럼 인증되지 않은 사용자 일 경우를 확인과
error.config._retry 객체에서 혹시 앞에서 또 함수를 호출 하지 않았는지 체크를 한다
11줄: 내가 만든 refreshAccessToken 함수로 세션 스토리지에 저장된 리프레쉬 토큰으로 액세스 토큰을 다시 재발급 받는다.
13줄: 앞에서 요청을 실패한 정보가 담긴 originalRequest의 headers의 토큰 값을
재발급 받은 accessToken으로 교체한다.
15줄: 재발급 받은 accessToken을 다시 세션스토리지에 저장을 한다.
17줄: 재발급 accessToken으로 교체된 앞에서 요청 실패한 객체를 다시 요청한다.
이번 예제에서는 인증되지 않은 토큰만 처리를 하였지만
응답 코드의 상황에 따라 응용 할 수 있을 것 이다.
나 같은 경우는 refreshToken 함수 안에서 알림 메시지와 페이지 이동을 시켰다.
미흡한 설명이지만 봐주셔서 감사합니다.
혹시 더좋은 방법 있을 경우 알려주시면 감사하겠습니다. ^^
'공부 > React' 카테고리의 다른 글
next js를 aws amplify로 겁나 쉽게 배포하기 (0) | 2020.11.17 |
---|---|
React-native expo 에서 모바일로 할때 핫로딩 안될때 (2) | 2018.10.11 |
리액트 컴포넌트 생명주기(Life Cycle) (2) | 2018.09.28 |
리액트 시작하기!! (5) | 2018.09.27 |