이전 글
[React] 리액트 refresh token 구현 (with. axios interceptor)
이전 코드
import axios from 'axios';
//토큰이 불필요한 경우
export const publicApi = axios.create({
baseURL: `${process.env.REACT_APP_SERVER_IP}`,
});
//토큰을 함께 보내는 instance
export const privateApi = axios.create({
baseURL: `${process.env.REACT_APP_SERVER_IP}`,
headers: {
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
},
});
//리프레시토큰 요청 api
function postRefreshToken() {
const response = publicApi.post('/api/v1/auth/refresh', {
refreshToken: localStorage.getItem('refreshToken'),
});
return response;
}
//리프레시 토큰 구현
privateApi.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
const {
config,
response: { status },
} = error;
if (status === 401) {
if (error.response.data.message === 'Unauthorized') {
const originRequest = config;
try {
const tokenResponse = await postRefreshToken();
if (tokenResponse.status === 201) {
const newAccessToken = tokenResponse.data.token;
localStorage.setItem('accessToken', tokenResponse.data.token);
localStorage.setItem(
'refreshToken',
tokenResponse.data.refreshToken,
);
axios.defaults.headers.common.Authorization = `Bearer ${newAccessToken}`;
originRequest.headers.Authorization = `Bearer ${newAccessToken}`;
return axios(originRequest);
}
} catch (error) {
if (axios.isAxiosError(error)) {
if (
error.response?.status === 404 ||
error.response?.status === 422
) {
alert(LOGIN.MESSAGE.EXPIRED);
window.location.replace('/sign-in');
} else {
alert(LOGIN.MESSAGE.ETC);
}
}
}
}
}
return Promise.reject(error);
},
);
문제 상황
이전 글에서 axios interceptor를 활용하여 refresh token을 구현했습니다. 이후 문제가 하나 발생했는데,
빨간색 요청이 401에러가 나온것이고, 이후 refresh token 요청이후 진행 중이던 요청을 제대로 완료하는 것을 볼 수 있습니다. 그러나 다시 한번 요청을 해보면 방금 토큰을 갱신했는데 또 유효하지 않은 토큰이라서 401응답이 오고 refresh api를 재요청 하는 것을 반복합니다.
위 코드를 읽어보면 알 수 있듯, 저는 새로운 토큰을 발급받아 로컬스토리지에 저장했습니다. 그리고 api 요청을 보낼 때 로컬 스토리지에서 꺼낸 토큰을 담아 보냅니다.
확인해보니 refresh token 응답이 제대로 오고, 로컬스토리지에도 바뀐 토큰이 즉시 저장되고 있었습니다.
그러나 그 다음 요청을 열어보니, 변경된 토큰을 보내지 않고 이전 토큰을 통해 요청하는 것을 확인했습니다.
해결 방법
privateApi.interceptors.request.use
를 이용해서 요청을 보낼 때 헤더의 토큰을 변경해서 보내주면 됩니다.
privateApi.interceptors.request.use((config) => {
const token = localStorage.getItem('accessToken');
config.headers.Authorization = 'Bearer ' + token;
return config;
});
이후 테스트해보니 변경된 토큰으로 잘 요청하는 것을 확인하였습니다.
'FE > react' 카테고리의 다른 글
[React] 리액트 carousel 라이브러리 없이 직접 구현하기 (0) | 2023.05.06 |
---|---|
[React] 모바일 웹 status bar 색상 변경하기 (0) | 2023.05.02 |
[React] github action 리액트 .env file 추가하기 (0) | 2023.04.25 |
[React] react프로젝트 github action으로 CI/CD 구축하기(aws S3, cloudfront) (0) | 2023.04.24 |
[React-query] useInfiniteQuery의 select로 반환값 변환하기 (0) | 2023.03.31 |
댓글