diff --git a/src/app/(post)/layout.tsx b/src/app/(post)/layout.tsx index 0dd4bfe..6dcb6bd 100644 --- a/src/app/(post)/layout.tsx +++ b/src/app/(post)/layout.tsx @@ -1,9 +1,14 @@ +'use client'; + import BackHeader from '@/components/BackHeader'; +import { useCheckSession } from '@/hooks/useCheckSession'; import { ReactNode } from 'react'; -export default function layout({ +export default function Layout({ children, }: Readonly<{ children: ReactNode }>) { + useCheckSession(); + return ( <> diff --git a/src/app/page.tsx b/src/app/page.tsx index 9e9b426..64008b0 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -8,9 +8,12 @@ import { apiService } from '@/services/apiService'; import { Post, PostCardProps } from '@/components/Post'; import CategoryList from '@/components/CategoryList'; import LiveFriends, { Friend } from '@/components/LiveFriendsList'; +import { useCheckSession } from '@/hooks/useCheckSession'; import s from './page.module.scss'; +consoleArt(); + interface PostReponse extends PostCardProps { memberUsername: string; category: string; @@ -31,12 +34,12 @@ export type CategoriesKR = keyof typeof categoryMap; export type CategoriesEN = (typeof categoryMap)[CategoriesKR]; export default function Home() { - consoleArt(); const [allPosts, setAllPosts] = useState([]); const [filteredPosts, setFilteredPosts] = useState([]); const [liveFriends, setLiveFriends] = useState([]); const [selectedCategory, setSelectedCategory] = useState('전부'); + useCheckSession(); const path = usePathname(); const handleCategoryClick: MouseEventHandler = (e) => { diff --git a/src/hooks/useCheckSession.ts b/src/hooks/useCheckSession.ts new file mode 100644 index 0000000..6a573ca --- /dev/null +++ b/src/hooks/useCheckSession.ts @@ -0,0 +1,22 @@ +import { apiService } from '@/services/apiService'; +import { useRouter } from 'next/navigation'; +import { useEffect } from 'react'; + +export const useCheckSession = () => { + const router = useRouter(); + + useEffect(() => { + async function checkSession() { + try { + await apiService.checkSession(); + } catch (error) { + if (error instanceof Error) { + alert(error.message); + router.push('/entry'); + } + } + } + + checkSession(); + }, [router]); +}; diff --git a/src/services/apiService.ts b/src/services/apiService.ts index 4fa8590..5091e4a 100644 --- a/src/services/apiService.ts +++ b/src/services/apiService.ts @@ -58,6 +58,23 @@ class ApiService { return res.text(); } + async checkSession() { + const res = await fetch(`${this.baseUrl}/session`, { + method: 'GET', + credentials: 'include', + }); + + if (!res.ok) { + const { status, error } = await res.json(); + + throw new Error( + `[${status}: ${error}] 세션이 만료되었습니다. 다시 로그인해주세요`, + ); + } + + return res.text(); + } + async fetchPosts() { const res = await fetch(`${this.baseUrl}/posts`, { method: 'GET',