From 441b9a03b514fa1d374b3ac85361917171625d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=91=ED=98=84?= Date: Tue, 10 Oct 2023 02:05:17 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9E=90=EB=8F=99=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EA=B5=AC=ED=98=84=20//tokens/refresh=EB=A1=9C=20?= =?UTF-8?q?=EB=A6=AC=ED=94=84=EB=A0=88=EC=8B=9C=20=ED=86=A0=ED=81=B0?= =?UTF-8?q?=EC=9D=84=20body=EC=97=90=20=EB=8B=B4=EC=95=84=EC=84=9C=20post?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EC=9A=94=EC=B2=AD=20=EC=84=B1=EA=B3=B5=20?= =?UTF-8?q?=EC=8B=9C=20=EC=9C=A0=ED=9A=A8=ED=95=9C=20=EC=97=91=EC=84=B8?= =?UTF-8?q?=EC=8A=A4=20=ED=86=A0=ED=81=B0=EC=9D=84=20=EB=B0=9B=EC=9D=8C=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EC=8B=A4=ED=8C=A8=20=EC=8B=9C=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=95=84=EC=9B=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/hooks/customHooks/useAutoLogout.ts | 68 ++++++-- client/src/hooks/customHooks/useOAuthLogin.ts | 120 ++++++++----- client/src/utils/setAutoLogoutAlarm.ts | 162 ++++++++---------- 3 files changed, 190 insertions(+), 160 deletions(-) diff --git a/client/src/hooks/customHooks/useAutoLogout.ts b/client/src/hooks/customHooks/useAutoLogout.ts index 3a300e0..5720102 100644 --- a/client/src/hooks/customHooks/useAutoLogout.ts +++ b/client/src/hooks/customHooks/useAutoLogout.ts @@ -7,6 +7,30 @@ import { secondAlarmTime, lastAlarmTime } from '../../utils/setAutoLogoutAlarm'; const useAutoLogout = () => { const dispatch = useDispatch(); + // 리프레시 토큰을 사용하여 새 엑세스 토큰을 요청하는 함수 + const requestNewAccessToken = async () => { + const refreshToken = localStorage.getItem("refreshToken"); + try { + const response = await fetch('http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080/tokens/refresh', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ refreshToken: refreshToken }) + }); + + if (response.status !== 201) { + throw new Error('Failed to fetch new access token'); + } + + const data = await response.json(); + return data.accessToken; + } catch (error) { + console.error(error); + return null; + } + }; + useEffect(() => { const accessToken = localStorage.getItem('accessToken'); if (accessToken !== null) { @@ -15,29 +39,35 @@ const useAutoLogout = () => { const autoLogoutLastAlarm = localStorage.getItem('autoLogoutLastAlarm'); if (autoLogoutSecondAlarm !== null) { - if (currentTime >= parseInt(autoLogoutSecondAlarm) + secondAlarmTime + lastAlarmTime) { - localStorage.removeItem('accessToken'); - localStorage.removeItem('refreshToken'); - localStorage.removeItem('autoLogoutSecondAlarm'); - } else { - const timeGone = currentTime - parseInt(autoLogoutSecondAlarm); - const remainTime = secondAlarmTime - timeGone; - dispatch(setLoginState()); - setAutoLogoutAlarm(dispatch, 'second', remainTime, lastAlarmTime); - } + if (currentTime >= parseInt(autoLogoutSecondAlarm) + secondAlarmTime) { + requestNewAccessToken().then(newAccessToken => { + if (newAccessToken) { + localStorage.setItem('accessToken', `Bearer ${newAccessToken}`); + dispatch(setLoginState()); + setAutoLogoutAlarm(dispatch, 'second', secondAlarmTime, lastAlarmTime); + } else { + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); + localStorage.removeItem('autoLogoutSecondAlarm'); + } + }); + } } if (autoLogoutLastAlarm !== null) { if (currentTime >= parseInt(autoLogoutLastAlarm) + lastAlarmTime) { - localStorage.removeItem('accessToken'); - localStorage.removeItem('refreshToken'); - localStorage.removeItem('autoLogoutLastAlarm'); - } else { - const timeGone = currentTime - parseInt(autoLogoutLastAlarm); - const remainTime = lastAlarmTime - timeGone; - dispatch(setLoginState()); - setAutoLogoutAlarm(dispatch, 'last', remainTime); - } + requestNewAccessToken().then(newAccessToken => { + if (newAccessToken) { + localStorage.setItem('accessToken', `Bearer ${newAccessToken}`); + dispatch(setLoginState()); + setAutoLogoutAlarm(dispatch, 'last', lastAlarmTime); + } else { + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); + localStorage.removeItem('autoLogoutLastAlarm'); + } + }); + } } } }, [dispatch]); diff --git a/client/src/hooks/customHooks/useOAuthLogin.ts b/client/src/hooks/customHooks/useOAuthLogin.ts index 10eab6b..4a5911a 100644 --- a/client/src/hooks/customHooks/useOAuthLogin.ts +++ b/client/src/hooks/customHooks/useOAuthLogin.ts @@ -5,58 +5,84 @@ import setAutoLogoutAlarm from '../../utils/setAutoLogoutAlarm'; import { secondAlarmTime, lastAlarmTime } from '../../utils/setAutoLogoutAlarm'; const useOAuthLogin = () => { - const dispatch = useDispatch(); - - useEffect(() => { - const urlParams = new URLSearchParams(window.location.search); - const accessToken = urlParams.get('access_token'); - const refreshToken = urlParams.get('refresh_token'); - const currentTime = Date.now(); - const autoLogoutSecondAlarm = localStorage.getItem('autoLogoutSecondAlarm'); - const autoLogoutLastAlarm = localStorage.getItem('autoLogoutLastAlarm'); - - if (accessToken && refreshToken) { - localStorage.setItem('accessToken', `Bearer ${accessToken}`); - localStorage.setItem('refreshToken', refreshToken); - - urlParams.delete('access_token'); - urlParams.delete('refresh_token'); - window.history.replaceState({}, '', '?' + urlParams.toString()); - - if (autoLogoutSecondAlarm === null) { - dispatch(setLoginState()); // 로그인 처리 - setAutoLogoutAlarm(dispatch, 'first', secondAlarmTime, lastAlarmTime); - } - - if (autoLogoutSecondAlarm !== null) { - if (currentTime >= parseInt(autoLogoutSecondAlarm) + secondAlarmTime + lastAlarmTime) { - localStorage.removeItem('accessToken'); - localStorage.removeItem('refreshToken'); - localStorage.removeItem('autoLogoutSecondAlarm'); - } else { - const timeGone = currentTime - parseInt(autoLogoutSecondAlarm); - const remainTime = secondAlarmTime - timeGone - dispatch(setLoginState()); // 로그인 처리 - setAutoLogoutAlarm(dispatch, 'second', remainTime, lastAlarmTime); + const dispatch = useDispatch(); + + // 리프레시 토큰을 사용하여 새 엑세스 토큰을 요청하는 함수 + const requestNewAccessToken = async () => { + const refreshToken = localStorage.getItem("refreshToken"); + try { + const response = await fetch('http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080/tokens/refresh', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ refreshToken: refreshToken }) + }); + + if (response.status !== 201) { + throw new Error('Failed to fetch new access token'); + } + + const data = await response.json(); + return data.accessToken; + } catch (error) { + console.error(error); + return null; } - } + }; + + useEffect(() => { + const urlParams = new URLSearchParams(window.location.search); + const accessToken = urlParams.get('access_token'); + const refreshToken = urlParams.get('refresh_token'); - if (autoLogoutLastAlarm !== null) { - if (currentTime >= parseInt(autoLogoutLastAlarm) + lastAlarmTime) { - localStorage.removeItem('accessToken'); - localStorage.removeItem('refreshToken'); - localStorage.removeItem('autoLogoutLastAlarm'); + if (accessToken && refreshToken) { + localStorage.setItem('accessToken', `Bearer ${accessToken}`); + localStorage.setItem('refreshToken', refreshToken); + + urlParams.delete('access_token'); + urlParams.delete('refresh_token'); + window.history.replaceState({}, '', '?' + urlParams.toString()); + + dispatch(setLoginState()); // 로그인 처리 + setAutoLogoutAlarm(dispatch, 'first', secondAlarmTime, lastAlarmTime); } else { - const timeGone = currentTime - parseInt(autoLogoutLastAlarm); - const remainTime = lastAlarmTime - timeGone; - dispatch(setLoginState()); // 로그인 처리 - setAutoLogoutAlarm(dispatch, 'last', remainTime); + const storedAccessToken = localStorage.getItem('accessToken'); + const currentTime = Date.now(); + const autoLogoutSecondAlarm = localStorage.getItem('autoLogoutSecondAlarm'); + const autoLogoutLastAlarm = localStorage.getItem('autoLogoutLastAlarm'); + + if (storedAccessToken) { + if (autoLogoutSecondAlarm && currentTime >= parseInt(autoLogoutSecondAlarm) + secondAlarmTime) { + requestNewAccessToken().then(newAccessToken => { + if (newAccessToken) { + localStorage.setItem('accessToken', `Bearer ${newAccessToken}`); + dispatch(setLoginState()); + } else { + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); + localStorage.removeItem('autoLogoutSecondAlarm'); + } + }); + } + + if (autoLogoutLastAlarm && currentTime >= parseInt(autoLogoutLastAlarm) + lastAlarmTime) { + requestNewAccessToken().then(newAccessToken => { + if (newAccessToken) { + localStorage.setItem('accessToken', `Bearer ${newAccessToken}`); + dispatch(setLoginState()); + } else { + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); + localStorage.removeItem('autoLogoutLastAlarm'); + } + }); + } + } } - } - } - }, [dispatch]); + }, [dispatch]); - return; + return; }; export default useOAuthLogin; diff --git a/client/src/utils/setAutoLogoutAlarm.ts b/client/src/utils/setAutoLogoutAlarm.ts index 8da5a1b..cd372a8 100644 --- a/client/src/utils/setAutoLogoutAlarm.ts +++ b/client/src/utils/setAutoLogoutAlarm.ts @@ -20,107 +20,81 @@ export const secondAlarmTime = 1000 * 60 * 29; // 29분 export const lastAlarmTime = 1000 * 60; // 1분 const setAutoLogoutAlarm = (dispatch: any, alarmNum: string, secondAlarmTime: number, lastAlarmTime?: number) => { - // 1~3차 알림 모두 설정 - if (alarmNum === alarmNumType.First) { - toast.warning("로그인 상태는 30분 동안 유지됩니다", { - style: toastStyle, - position: "top-center", - }); - - // 2차 알림 셋팅 시간 기록 - const autoLogoutSecondAlarm = Date.now(); - localStorage.setItem("autoLogoutSecondAlarm", `${autoLogoutSecondAlarm}`); - - setTimeout(() => { - // 2차 알림 셋팅 시간 제거 - localStorage.removeItem("autoLogoutSecondAlarm"); - - toast.warning("1분 뒤 로그아웃 처리됩니다", { - style: toastStyle, - position: "top-center", - }); - - // 3차 알림 셋팅 시간 기록 - const autoLogoutLastAlarm = Date.now(); - localStorage.setItem("autoLogoutLastAlarm", `${autoLogoutLastAlarm}`); - - setTimeout(() => { - // 3차 알림 셋팅 시간 제거 - localStorage.removeItem("autoLogoutLastAlarm"); - - dispatch(setLogoutState()); - localStorage.removeItem("accessToken"); - localStorage.removeItem("refreshToken"); - - toast.warning("로그아웃 처리되었습니다", { - style: toastStyle, - position: "top-center", + // 리프레시 토큰을 사용하여 새 엑세스 토큰을 요청하는 함수 + const requestNewAccessToken = async () => { + const refreshToken = localStorage.getItem("refreshToken"); + try { + const response = await fetch('http://ec2-13-125-246-160.ap-northeast-2.compute.amazonaws.com:8080/tokens/refresh', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ refreshToken: refreshToken }) + }); + + if (response.status !== 201) { + throw new Error('Failed to fetch new access token'); + } + + const data = await response.json(); + return data.accessToken; + } catch (error) { + console.error(error); + return null; + } + }; + + const handleTokenRefresh = async () => { + const newAccessToken = await requestNewAccessToken(); + + if (newAccessToken) { + sessionStorage.setItem("accessToken", `Bearer ${newAccessToken}`); + toast.success("로그인이 연장되었습니다", { style: toastStyle, position: "top-center" }); + } else { + dispatch(setLogoutState()); + localStorage.removeItem("accessToken"); + localStorage.removeItem("refreshToken"); + toast.warning("로그아웃 처리되었습니다", { style: toastStyle, position: "top-center" }); + } + }; + + if (alarmNum === alarmNumType.First) { + toast.warning("로그인 상태는 30분 동안 유지됩니다", { + style: toastStyle, + position: "top-center", }); - }, lastAlarmTime); - }, secondAlarmTime); - } - - // 2~3차 알림 설정 - if (alarmNum === alarmNumType.Second) { - setTimeout(() => { - // 2차 알림 셋팅 시간 제거 - localStorage.removeItem("autoLogoutSecondAlarm"); - - toast.warning("1분 뒤 로그아웃 처리됩니다", { - style: toastStyle, - position: "top-center", - }); - - // 3차 알림 셋팅 시간 기록 - const autoLogoutLastAlarm = Date.now(); - localStorage.setItem("autoLogoutLastAlarm", `${autoLogoutLastAlarm}`); - - setTimeout(() => { - // 3차 알림 셋팅 시간 제거 - localStorage.removeItem("autoLogoutLastAlarm"); - - dispatch(setLogoutState()); - localStorage.removeItem("accessToken"); - localStorage.removeItem("refreshToken"); - - toast.warning("로그아웃 처리되었습니다", { - style: toastStyle, - position: "top-center", - }); - }, lastAlarmTime); - }, secondAlarmTime); - - return; - } - - // 3차 알림만 설정 - if (alarmNum === alarmNumType.Last) { - setTimeout(() => { - // 3차 알림 셋팅 시간 제거 - localStorage.removeItem("autoLogoutLastAlarm"); - - dispatch(setLogoutState()); - localStorage.removeItem("accessToken"); - localStorage.removeItem("refreshToken"); - - toast.warning("로그아웃 처리되었습니다", { - style: toastStyle, - position: "top-center", - }); - }, lastAlarmTime); - } + + const autoLogoutSecondAlarm = Date.now(); + localStorage.setItem("autoLogoutSecondAlarm", `${autoLogoutSecondAlarm}`); + + setTimeout(handleTokenRefresh, secondAlarmTime); + } + + if (alarmNum === alarmNumType.Second) { + setTimeout(handleTokenRefresh, secondAlarmTime); + } + + // 3차 알림만 설정 + if (alarmNum === alarmNumType.Last) { + setTimeout(() => { + dispatch(setLogoutState()); + localStorage.removeItem("accessToken"); + localStorage.removeItem("refreshToken"); + toast.warning("로그아웃 처리되었습니다", { style: toastStyle, position: "top-center" }); + }, lastAlarmTime); + } }; export default setAutoLogoutAlarm; const alarmNumType = { - First: "first", - Second: "second", - Last: "last", + First: "first", + Second: "second", + Last: "last", }; const toastStyle = { - fontSize: "15px", - fontWeight: 350, - color: "black", + fontSize: "15px", + fontWeight: 350, + color: "black", };