backend에서 jwt의 유효시간을 설정했을 때,토큰의 유효시간을 프론트단에서 어떻게 반영해야 할까?
const authSubmitHandler = async(e) => {
//...
try{
const responseData = await sendRequest(
'http://localhost:5050/api/users/login',
'POST',
JSON.stringify({
email:formState.inputs.email.value,
password:formState.inputs.password.value
}),
{
'Content-Type': 'application/json'
}
);
// responseData는 userId,email,token을 반환한다.
// login 함수는 3개의 인수를 받는다.
// 3번째 인자를 입력하지 않으면 함수 내부에서 expiration date를 생성하도록 작성하였다.
login(responseData.userId, responseData.token);
navigate('/');
}catch(err){
// ...
const [token, setToken] = useState('');
const [userId, setUserId] = useState(false);
const [tokenExpirationDate, setTokenExpirationDate] = useState()
const login = useCallback((uid,token,expirationDate)=>{
setToken(token);
setUserId(uid);
// 3번째 매개변수가 비어있을 시, 초깃값 1시간 설정
const tokenExpiration = expirationDate || new Date(new Date().getTime() + 60 * 1000 * 60);
setTokenExpirationDate(tokenExpiration)
// login이 유지되는 로직을 작성하기 위해 localStorage에 저장.
localStorage.setItem('user',JSON.stringify({
userId: uid,
token,
expiration: tokenExpiration.toISOString()
}))
},[])
login 함수 사용
login의 여부에 따라 전체 application의 작동이 달라지기 때문에
login은 application의 최상단에 위치해야 한다.
//app.js
useEffect(()=>{
const currentUserData = JSON.parse(localStorage.getItem('user'));
// token을 저장한 시간보다 현재 시간이 크다는 것은, 접속 후 1시간(설정시간)이 지나지 않았다는 것을 의미한다.
if(currentUserData && new Date(currentUserData.expiration) > new Date()){
login(currentUserData.userId,currentUserData.token,new Date(currentUserData.expiration))
}
},[login])
const logout = useCallback(()=>{
setToken(null);
setUserId(null);
setTokenExpirationDate(null);
localStorage.removeItem('user');
},[])
let logoutTimer
useEffect(()=>{
if(token && tokenExpirationDate){
const remainingTime = tokenExpirationDate.getTime() - new Date().getTime();
logoutTimer = setTimeout(logout,remainingTime)
}else{
clearTimeout(logoutTimer)
}
},[token,logout,tokenExpirationDate])