트러블 슈팅(Token 재발급 후 페이지 이동 이슈)
① 문제
- axios interceptors를 사용해 axios가 서버로 HTTP 요청을 보내기 전, refresh Token으로 만료된 access Token을 재발급 받도로록 구현함.
- try catch문을 사용해 에러가 발생했을 때는 쿠키에 저장된 refresh Token과 로컬스토리지에 저장된 access Token을 모두 지우고 로그인 화면으로 이동하도록 useNavigate를 사용했는데, 페이지 이동이 되지 않는 이슈가 발생함.
② 시도
1) 토큰 재발급 코드 위치 변경 : axios interceptors → Layout
- axios interceptors는 useNavigate가 실행되지 않아 모든 페이지에 영향을 주는 Layout으로 옮겨서 Token 재발급 코드를 작성함
2) Layout 이동 후 : useNavigate는 동작하나, 토큰 재발급을 후 렌더링 이슈 발생
- 코드 위치를 바꾸고 나서 useNavigate는 잘 동작하지만, 각 페이지가 바로 렌더링되지 않고, 새로고침을 눌러야 렌더링이 되는 문제가 발생함.
③ 해결
- 리액트 훅(useNavigate, useEffect 등등)은 jsx파일이거나, 커스텀훅(use000.jsx) 파일에서만 쓸 수 있었음.
- interceptors는 js 파일이기때문에 useNavigate를 사용하는 대신에 window.location.href = "/login";로 수정해 문제를 해결함.
// accessToken 재발급
axiosInstance.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
// 액세스 토큰 만료됐을 때,
if (error.response.data.status === 500) {
const refreshToken = getCookie("refreshToken"); // 리프레시 토큰 가져오고,
localStorage.removeItem("accessToken"); // 엑세스 토큰은 지우기(axiosInstance 기본설정 때문에 post 보낼때 같이 보내지는데, 403 에러남!)
console.log("액세스 토큰 만료", error);
console.log("refreshToken 있니?", refreshToken);
// 1. 리프레시 토큰이 있으면,
if (refreshToken) {
try {
// 재발급 API로 리프레시 토큰 보내서
const response = await axiosInstance.post(
"/api/token/refreshAccessToken",
null, // 요청 body 보내지 않음
{
headers: {
Authorization_refresh: refreshToken,
},
}
);
console.log("리프레시 있을 때 response", response);
// 새로운 토큰(액세스/리프레시) 받고, 저장하기
const newAccessToken = response.data.accessToken;
const newRefreshToken = response.data.refreshToken;
localStorage.setItem("accessToken", newAccessToken);
setCookie("refreshToken", newRefreshToken, {
path: "/", // 모든 페이지에서 쿠키 접근 가능
secure: true, // https로 통신할때만 쿠키 저장됨
// httpOnly: true, // HttpOnly 속성을 적용(js 접근 불가) > 클라이언트에서 저장안됨
});
error.config.headers["Authorization"] = newAccessToken; // 업데이트된 액세스 토큰을 헤더에 설정하고 현재 요청을 다시 실행
return axiosInstance(error.config); // 현재 요청을 새로운 액세스 토큰을 가지고 재시도
// 2. 리프레시 토큰 에러면,
} catch (refreshError) {
console.log("리프레시 에러 refreshError", refreshError);
// 토큰(액세스/리프레시) 지우고, 재로그인 시키기
localStorage.removeItem("accessToken");
removeCookie("refreshToken");
window.location.href = "/login";
alert("재로그인이 필요합니다.");
}
} else {
// 토큰(액세스/리프레시) 지우고, 재로그인 시키기
localStorage.removeItem("accessToken");
removeCookie("refreshToken");
window.location.href = "/login";
alert("재로그인이 필요합니다.");
}
}
// 다른 오류의 경우, 오류를 다시 반환
return Promise.reject(error);
}
);
'⛵ 항해99 > TIL · WIL ✏️' 카테고리의 다른 글
[TIL] 2023.11.14 - 트러블 슈팅(카카오톡 공유하기 시 뒤로가기 이슈) (0) | 2023.11.20 |
---|---|
[TIL] 2023.11.11 - 트러블 슈팅(프로필 사진 put 적용 이슈) (0) | 2023.11.11 |
[TIL] 2023.11.10 - enter 눌러서 로그인하기 (0) | 2023.11.11 |
[TIL] 2023.11.09 - 무한 스크롤 구현(react-intersection-observer) (0) | 2023.11.09 |
[TIL] 2023.11.08 - JWT Access Token / Refresh Token 구현 (0) | 2023.11.09 |