관제 시스템 프로젝트 중 로그인 연장 버튼을 누르면 로그인 상태를 연장 시키는 기능을 넣어야 해서 react-idle-timer 를 활용해서 제작하여 react-idle-timer 사용 방법에 대해 정리해보았습니다.
react-idle-timer
React 애플리케이션에서 사용자가 일정 시간 동안 비활성 상태일 때 특정 작업을 수행하도록 돕는 라이브러리입니다. 예를 들어, 사용자가 일정 시간 동안 키보드나 마우스 등의 입력을 하지 않는 경우 세션을 만료시키거나, 경고 메시지를 띄우는 등의 기능을 구현할 수 있습니다.
선택 이유
주요 기능
주요 옵션
문제 해결
사용법
npm
Homepage
react-idle-timer 설치
npm i react-idle-timer // or yarn add react-idle-timer
import
import { useIdleTimer } from 'react-idle-timer'
1시간 타이머
먼저 시각적으로 1시간이 흐르는 타이머를 보여줍니다.
function millisToMinutesAndSeconds(millis: number) { const minutes = Math.floor(millis / 60000); const seconds = Math.floor((millis % 60000) / 1000); const addZeroMinutes = Number(minutes) < 10 ? "0" + minutes : minutes; const addZeroSeconds = Number(seconds) < 10 ? "0" + seconds : seconds; return addZeroMinutes + " : " + addZeroSeconds; }
react-idle-timer 설정
useIdleTimer에서 getRemainingTime, reset 를 가져옵니다.
timeout : 로그인 유지 시간 (ex. 60분 = 3600000, 10분 = 600000, 1분 = 60000 )
events : 활동을 감시할 DOM 이벤트 종류
throttle : onAction지연을 밀리 초 단위로 설정하여 기능을 조절합니다. ( 일정 시간 동안 요청이 한 번만 수행되도록 한다. )
const { getRemainingTime, reset } = useIdleTimer({ timeout: 3600000, //60분 events: [], throttle: 500, });
이 외에도 다양한 Props 들이 있습니다.
타이머 setInterval
이제 페이지에 진입 했을 때 setInterval 함수를 사용하여 500ms(0.5초)마다 getRemainingTime 함수를 호출하고, 그 결과를 setRemaining 함수를 통해 상태(state)에 업데이트하여 시간을 보여줍니다.
useEffect(() => { const interval = setInterval(() => { setRemaining(getRemainingTime()); }, 500); return () => { clearInterval(interval); }; });
자동 로그아웃 & 로그인 연장
그리고 remaining을 관찰하여 remaining이 0이 되면 alert창이 뜨면서 로그아웃이 되며 로그인 페이지로 이동합니다.
만약 onClick 이벤트로 loginExtension 함수가 걸린 버튼을 누르면 useIdleTimer에 있는 reset을 실해해 타임이 다시 리셋 됩니다.
useEffect(() => { if (remaining === 0) { alert("토큰이 만료되어 로그인 페이지로 이동합니다."); signOut({ callbackUrl: `${url}` }); } }, [remaining]); const loginExtension = () => { reset(); };
전체 코드
import { signOut, useSession } from "next-auth/react"; import { useIdleTimer } from "react-idle-timer"; export default function Home() { // 1시간 카운트 function millisToMinutesAndSeconds(millis: number) { const minutes = Math.floor(millis / 60000); const seconds = Math.floor((millis % 60000) / 1000); const addZeroMinutes = Number(minutes) < 10 ? "0" + minutes : minutes; const addZeroSeconds = Number(seconds) < 10 ? "0" + seconds : seconds; return addZeroMinutes + " : " + addZeroSeconds; } // 로그인 연장 const url = "/login"; const [remaining, setRemaining] = useState<number>(null); const { getRemainingTime, reset } = useIdleTimer({ timeout: 3600000, //60분 events: [], throttle: 500, }); useEffect(() => { const interval = setInterval(() => { setRemaining(getRemainingTime()); }, 500); return () => { clearInterval(interval); }; }); useEffect(() => { if (remaining === 0) { alert("토큰이 만료되어 로그인 페이지로 이동합니다."); signOut({ callbackUrl: `${url}` }); } }, [remaining]); const loginExtension = () => { reset(); }; return ( <> <Seo /> <section css={HomePage}> <div> <span style={{ marginRight: "5px" }}> {millisToMinutesAndSeconds(remaining)} </span> <button onClick={loginExtension} style={{ padding: "12px", marginLeft: "10px", borderRadius: "10px", color: "#fff", backgroundColor: "rgb(215 97 0)", }} > 로그인 연장 </button> </div> </section> </> ); }
로그인 연장
자동 로그아웃