티스토리 뷰
프로젝트를 진행하면서 부족한 부분들이 생긴다.
그래서 프로젝트를 하면서 중간중간 리펙토링도 많고 추가 해야하는 기능도 많아 두서없는 TIL을 쓰게 된다.. ㅎ
쨋든.
📖AxiosInstance 이외에 토큰 만료처리가 필요한 이유.
API를 요청하는 특정 페이지로 이동하기 전에 refreshToken이 만료되었는지 확인이 필요했다.
❓refreshToken이 만료되었는지 확인하는 이유.
백엔드로부터 ` accessToken `을 받아 localstorage에 저장해 사용하고
토큰을 디코딩하여 추가로 localstorege에 user로 저장하여 로그인 상태유지, 접근 제어 등에 사용하고 있다.
⬇️localstorage에 저장한 이유
이때 문제가 refreshToken이 만료되면 로그인을 다시 필요로 하는데,
api 요청을 해 refreshToken 만료여부를 확인하기 전까지는 계속 로그인을 유지하는것이 문제가 되었다.
특히 글 등록페이지에서 api요청이 필요한 곳들이 있는데 그때가서 로그인페이지로 리다이렉션..
그래서 localstorage에 담은 값을 신선하게 해줄 타이밍이 필요했다.
⭐ 초기에 해결 방안으로 생각한 setTimeout
사용자가 로그인했을때의 시간을 타임스탬프로 남겨 setTimeout을 이용해 24시간 후에 localStorage에서 삭제할까 싶었으나 문제점이 많았다.
🔥문제점
1. 브라우저 창을 닫게되면 setTimeout은 작동을 멈춤.
2. 사용자가 여러개의 탭을 열어두는 경우 중복된 타이머 발생. (백엔드가 중복 로그인 방지해두어 무시가능)
3. 브라우저가 비활성화 상태일 경우 타이머의 정확도 떨어짐.
4. 백앤드가 refreshToken 만료시간을 정해두었음에도 불구하고 프론트에서 시간을 임의로 정하여 로그아웃 시키고 재로그인을 하게 하는 것은 전혀 불필요한 행동... 이라고 나만의 생각..
💡해결방법
accesstoken을 디코딩해보면 토큰 발급시간과 만료시간을 함께 담아 보내주었다.
나는 디코딩한 값을 user라는 key로 localstorage에 저장
그래서 만료시간을 활용해 `timeStamp` 와 `expirationTime`이라는 유틸리티 함수를 만들었다.
` expirationTime `은 api 요청이 필요한 페이지로 리다이렉션 되는 버튼에서 호출해주면 된다.
timeStamp의 역할
1. 토큰을 디코딩하여 담아둔 값 중 만료시간 불러와 밀리초 단위로 변환
2. 만료시간과 현재시간을 비교
3. 만료시간이 현재시간보다 크다면 false를 반환 그렇지 않은 경우는 true를 반환
expirationTime의 역할
1. timeStamp 호출하여 true인지 false인지 확인
2. true인 경우 accessToken 재발급 요청
토큰 만료를 확인하고 필요 시 accessToken 요청.
accessToken 요청 시 refreshToken을 함께 보내는데 refreshToken이 만료된 경우 로그인 페이지로 리다이렉션
👩💻코드 살펴보기
< timeStamp >
1. localsotrage에 key중 user 호출
const getLoginUserInfo = localStorage.getItem("user");
2. 호출된 값 JSON 형식으로 파싱
const userObj = JSON.parse(getLoginUserInfo);
3. 만료시간을 초단위에서 밀리초 단위로 변환
const expValue = userObj.state.user.exp * 1000;
❓ Date.getTime() 메서드는 현재 시간을 밀리초 단위의 타임스탬프로 반환하고,
exp는 초단위로 저장. 두값을 비교하기 위해 초단위를 일치시켜주어야함. 만료시간 key가 exp
4. 현재 시간 구하기
const nowTime = new Date().getTime();
5. 현재시간과 만료시간을 비교해 현재시간이 큰 경우 true 반환
return nowTime > expValue;
6. 현재시간과 만료시간을 비교해 만료시간이 더 큰 경우 false 반환
return false;
< timeStamp 전체코드 >
const timeStamp = () => {
const getLoginUserInfo = localStorage.getItem("user");
if (getLoginUserInfo) {
const userObj = JSON.parse(getLoginUserInfo);
const expValue = userObj.state.user.exp * 1000;
const nowTime = new Date().getTime();
return nowTime > expValue;
}
return false;
};
< expirationTime 전체코드 >
export const expirationTime = async () => {
if (timeStamp()) {
await getNewAccessToken();
}
};
` timeStamp ` 호출해 true인 경우 accessToken 재발행을 도와줄 getNewAccessToken 호출!!!
🍀사용방법
import { expirationTime } from "@/utils/timeStamp";
const handleMenuClick = async (menu: MenuType) => {
if (menu.signOut) {
router.replace(menu.url);
logOutMutate();
clearUser();
} else {
if (menu.id === 4) {
await expirationTime();
}
router.replace(menu.url);
}
setShowMenu(false);
};
메뉴를 드롭다운할때 사용하는 함수인데, menu.id === 4 인 경우 글등록페이지로 리다이렉션 된다.
글 등록페이지는 api 요청이 아주 많은 곳이다.
때문에 글 등록페이지로 리다이렉션 되기 전에 expirationTime 를 호출!!
` expirationTime `를 호출했을때 예상 작동
1. timeStamp가 false인 경우에는 바로 글 등록페이지로 리다이렉션
2. accessToken 만료 시 accessToken 요청.
3. refreshToken이 만료되지 않았다면 accessToken 재발행 후 글 등록페이지로 리다이렉션
4. refreshToken 만료 시 로그인페이지로 리다이렉션.
⬇️getNewAccessToken 코드가 궁금하신 분들은 아래 블로그를 확인해주세요😃
https://anywhereim.tistory.com/112
'TIL' 카테고리의 다른 글
access, refresh token의 개념과 관리 방법 요약본 (1) | 2024.07.08 |
---|---|
axiosInstance 리펙토링하기 (0) | 2024.07.06 |
react-hook-form 나홀로 정리하기 (0) | 2024.07.02 |
무한스크롤 쉽게 구현하기 (0) | 2024.06.25 |
Zustand 이용해 컨펌창 만들기 (2) | 2024.06.24 |
- Total
- Today
- Yesterday
- 영화별점만들기
- styled component 설치방법
- Warning: A component is changing an uncontrolled input to be controlled.
- readme작성해보기
- readme 작성 방법
- axiosinstance 사용 시 토큰 사용 법
- readme 이미지 추가 방법
- simple Icon 사용방법
- axios 설치하기
- nextjs 토큰 만료처리하기
- 유효성검사 css
- styled component GlobalStyle 사용방법
- 별점 색채우기
- 에러모음집
- Warning: Each child in a list should have a unique "key" prop.
- 유효성검사
- axios instance 작성하기
- axios 사용하기
- styled component 조건부 사용방법
- 영화 별점
- readme 작성해야 하는 이유
- readme 역할
- Warning: validateDOMNesting(...): <li> cannot appear as a descendant of <li>
- 별점만들기
- git cache
- styled component 사용방법
- axios CRUD
- Fetch와 Axios 의 장단점
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |