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',