타이머를 활용한 토큰 삭제 훅에서 새로고침을 하면 타이머가 초기화되는 문제점 해결하는 과정을 기록했다.
저번에 토큰 삭제 hook 생성을 하고 일정 시간이 지나면 액세스 토큰을 삭제하여 자동 로그아웃 처리를 하도록 만들었다. 임의로 타이머를 1분으로 설정해두고 테스트를 해봤을 땐 제대로 로그아웃이 되었고 별다른 문제가 없다고 생각했는데 문제가 한둘이 아니었다. ^^;
useRef
를 사용했다. 이유는 현재 저장하고 싶은 값을 리렌더링없이 저장할 수 있고 DOM을 참조할 수 있다는 점에서 useState보다는 useRef를 사용하는 게 맞지 않을까? 싶었기 때문이다. Math.floor
를 통하여 정수를 반환하도록 로직을 수정했다.
localStorage.setItem(
"startTime",
Math.floor(startTimeRef.current).toString()
);
localStorage.setItem(
"remainingTime",
Math.floor(remainingTimeRef.current).toString()
);
startTimeRef
와 remainingTimeRef
는 useRef 훅을 사용하여 각각 시작 시간과 남은 시간을 저장하기 위해 사용했다. const deleteToken = (): void => {
cookie.remove("accessToken", { path: "/" });
dispatch(resetLog());
router.replace("/");
};
const waitTime = 24 * 60 * 60 * 1000; // 원하는 시간
if (accessToken) {
const storedStartTime = localStorage.getItem("startTime");
const storedRemainingTime = localStorage.getItem("remainingTime");
const currentTime = Date.now();
const elapsedTime = storedStartTime
? currentTime - parseInt(storedStartTime)
: 0;
const remainingTime = storedRemainingTime
? parseInt(storedRemainingTime) - elapsedTime
: waitTime;
if (remainingTime > 0) {
timerRef.current = setTimeout(deleteToken, remainingTime);
startTimeRef.current = currentTime;
remainingTimeRef.current = remainingTime;
} else {
deleteToken();
}
} else {
clearTimeout(timerRef.current!);
startTimeRef.current = null;
remainingTimeRef.current = 0;
localStorage.removeItem("startTime");
localStorage.removeItem("remainingTime");
}
setInterval
을 사용하여 1초마다 남은 시간을 감소시키고 해당 값을 콘솔에 띄우도록 로직을 작성하였다. useEffect(() => {
if (accessToken) {
const interval = setInterval(() => {
const remainingSeconds = Math.floor(remainingTimeRef.current / 1000);
console.log("Remaining time:", remainingSeconds, "seconds");
remainingTimeRef.current -= 1000;
}, 1000);
return (): void => {
clearInterval(interval);
};
}
}, [accessToken]);
페이지를 새로고침 하여도 타이머가 초기화되지 않고 일정 시간이 지난 후 자동 로그아웃이 되는 걸 확인하였다.
결론적으로 이런 과정 없이 백엔드 api를 통하여 토큰 만료 여부에 관해 통신을 하고, 리프레시 토큰을 활용하여 토큰을 재발급 api를 사용하여 silent하게 로그인을 유지하는 로직을 완성할 수 있다.
그러나 해당 에러를 직면했을 때는 이미 기능 구현과 팀 프로젝트가 완료된 상태고 배포도 완료된 상태라 프론트엔드단에서 이 문제를 해결할 수 있는 방법을 생각하다보니,, 일정 시간이 지나면 로그아웃을 하도록 수정하는 방법이 최선이라고 판단했다.
로그인 과정은 정말.. 생각할수록 쉽지 않다고 느꼈다. 개발을 처음 시작해본 입장으로 로그인 과정을 제대로 해내지 못해서 정말 아쉽다. 부족한 경험 대비 너무 많은 기능 구현을 맡게 되어서 시간 안에 해내는 데만 급급했다. 난이도 있는 순으로 기능을 나열하여 팀원들과 조금만 더 상의하고 파트를 분배했다면 로그인 구현에 집중할 수 있었을 거라는 아쉬움이 있다. ㅠㅠ
백엔드와의 커뮤니케이션도 아쉬웠다. 팀플이 처음이고 서로의 로직을 구현하는 데에만 열중하다보니 놓치고 가는 부분이 있어서 그 간극을 조금만 해소할 수 있었다면 배포 전에 기능을 다 완성할 수 있었을 텐데 나의 부족함을 체감했다. 로그인 전반에 대해 경험을 해봤거나 프론트나 백 둘 다 지식이 있는 사람이 한 명이라도 있다면 로그인 로직을 다룰 때 좀 더 유리하다고 생각한다.
이런 어려움을 경험했으니 다음 기회에서는 더 잘 할 수 있을 거라고 확신한다..!
- 첫 팀플에 첫 로그인 기능을 맡았다면 신중하게 고민해보자. 😢
- 적어도 로그인 경험이 있는 사람과 페어를 이루어서 작업하는 것이 효율적이다.
- 불가능을 빠르게 판단하여 대안을 내는 것도 하나의 능력이다..!