diff --git a/client/src/App.tsx b/client/src/App.tsx index 7ad636f..4efabf9 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import { Provider } from 'react-redux'; import './App.css'; @@ -21,6 +21,8 @@ import MyPageMain from './pages/MyPageMain'; import MyPageInfo from './pages/MyPageInfo'; import MyPost from './pages/MyPost'; +import ProtectedRoute from 'components/ProtectedRoute'; + const App: React.FC = () => { return ( @@ -28,20 +30,24 @@ const App: React.FC = () => { - } /> + } /> } /> - } /> + } /> } /> } /> } /> } /> } /> - } /> - } /> - } /> + }> + } /> + + } /> + } /> + } /> + diff --git a/client/src/components/GuestHeader.tsx b/client/src/components/GuestHeader.tsx index 3e6c46a..8177579 100644 --- a/client/src/components/GuestHeader.tsx +++ b/client/src/components/GuestHeader.tsx @@ -1,16 +1,22 @@ import React from 'react'; -import { Link } from 'react-router-dom'; +import { Link, useNavigate } from 'react-router-dom'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faPencil, faRightToBracket } from "@fortawesome/free-solid-svg-icons"; import { GuestHeaderProps } from 'types/types.ts'; import logo from '../assets/logo.png'; -const GuestHeader: React.FC = ( { isLoggedIn } ) => { +const GuestHeader: React.FC = ({ isLoggedIn }) => { + const navigate = useNavigate(); if (isLoggedIn) { return null; } + const handleWriteCilck = () => { + alert('로그인 후 글쓰기가 가능합니다. 로그인 페이지로 이어드릴게요.'); + navigate('/login'); + }; + return (
@@ -18,9 +24,9 @@ const GuestHeader: React.FC = ( { isLoggedIn } ) => { logo
- +
- +
diff --git a/client/src/components/ProtectedRoute.tsx b/client/src/components/ProtectedRoute.tsx new file mode 100644 index 0000000..992c1b7 --- /dev/null +++ b/client/src/components/ProtectedRoute.tsx @@ -0,0 +1,33 @@ +import React, { useEffect } from 'react'; +import { Navigate, Outlet } from 'react-router-dom'; + +const logout = (): void => { + localStorage.removeItem('accessToekn'); +} + +const ProtectedRoute: React.FC = () => { + const getAccessToken = (): string | null => { + return localStorage.getItem('accessToken'); + } + + const isTokenExpired = (token: string | null): boolean => { + if (!token) return true; + + const payload = JSON.parse(atob(token.split('.')[1])); + const currentTime = Math.floor(Date.now() / 1000); + + return payload.exp < currentTime; + } + + const token = getAccessToken(); + const isExpired = isTokenExpired(token); + + if (isExpired) { + logout(); + return ; + } + + return ; +}; + +export default ProtectedRoute; \ No newline at end of file diff --git a/client/src/pages/LoginPage.tsx b/client/src/pages/LoginPage.tsx index c13f226..2a4967e 100644 --- a/client/src/pages/LoginPage.tsx +++ b/client/src/pages/LoginPage.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { postLogin } from 'api/api.js'; import { useDispatch } from 'react-redux'; import { setActiveMenu } from '../store/menuSlice.ts';