SSR 시 로그인 유지 (cookies().get() 이용)
- 페이지 진입 시 서버에서 쿠키(token)를 읽고
- Redux에 로그인 정보를 세팅하여
- 새로고침하거나 직접 URL로 접속해도 로그인 상태 유지
방법
- app/page.tsx를 서버 컴포넌트로 만들고
- cookies()를 이용해 쿠키에서 token을 읽어옴
- Redux 초기화를 위한 상태 전달은 props 또는 hydration 방식
1. app/page.tsx → 서버 컴포넌트로 변경
// app/page.tsx (❌ "use client" 제거)
import { cookies } from "next/headers";
import HomeClient from "./HomeClient";
export default function HomePage() {
const cookieStore = cookies();
const token = cookieStore.get("token")?.value;
// 토큰이 있다면 임의 유저 정보 설정 (실제 프로젝트에선 API 호출 필요)
const user = token
? { id: "1", name: "테스트유저", email: "test@test.com" }
: null;
return <HomeClient user={user} token={token} />;
}
2. 클라이언트 컴포넌트 분리 (app/HomeClient.tsx)
'use client';
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from '@/store';
import { logout, setAuth } from '@/store/slices/authSlice';
import { useRouter } from 'next/navigation';
interface Props {
user: {
id: string;
name: string;
email: string;
} | null;
token: string | null;
}
export default function HomeClient({ user, token }: Props) {
const reduxUser = useSelector((state: RootState) => state.auth.user);
const dispatch = useDispatch();
const router = useRouter();
// 클라이언트에서 Redux 초기화 (최초 진입 시 1회만)
useEffect(() => {
if (user && token) {
dispatch(setAuth({ user, token }));
}
}, [dispatch, user, token]);
const handleLogout = async () => {
await fetch('/api/logout');
dispatch(logout());
router.push('/login');
};
return (
<main className="p-10">
<h1 className="text-2xl font-bold">홈페이지</h1>
{reduxUser ? (
<>
<p className="mt-4">환영합니다, {reduxUser.name}님!</p>
<button
onClick={handleLogout}
className="mt-4 bg-red-500 text-white px-4 py-2 rounded"
>
로그아웃
</button>
</>
) : (
<div className="mt-4 text-red-500">
<p>로그인하지 않았습니다.</p>
<button
onClick={() => router.push('/login')}
className="mt-2 bg-blue-500 text-white px-4 py-2 rounded"
>
로그인하러 가기
</button>
</div>
)}
</main>
);
}
| 위치 | 동작 |
| app/page.tsx | 서버에서 cookies()로 토큰 추출 |
| HomeClient.tsx | 클라이언트에서 Redux 상태 초기화 (setAuth) |
| 페이지 새로고침 시 | 서버 + 클라이언트 분리 작동 → 로그인 유지됨 |
로그인 보호 미들웨어 (middleware.ts)
- 로그인 안 된 사용자가 특정 페이지에 접근하면 /login으로 리다이렉트
middleware란
요청(Request)이 들어올 때 그것을 가로채서 검사하거나 조작하고, 다음 단계로 넘겨주는 역할을 합니다.
Next.js에서의 middleware는 페이지가 렌더링되기 전에 실행되는 서버 사이드 코드입니다.
1. middleware.ts 생성
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value;
const protectedPaths = ['/mypage', '/settings'];
const pathname = request.nextUrl.pathname;
const isProtected = protectedPaths.includes(pathname);
if (isProtected && !token) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
| 상황 | 결과 |
| 로그인 쿠키가 있으면 | SSR에서 Redux에 로그인 상태 저장 |
| 로그인 쿠키가 없는데 보호 페이지 접근 | middleware가 /login으로 리다이렉트 |
| 로그인하면 쿠키 + Redux 저장됨 | 새로고침해도 유지됨 |
| 로그아웃하면 쿠키 제거 + Redux 초기화 | 접근 시 /login으로 튕김 |
'개발 공부 > React' 카테고리의 다른 글
| Next.js - 동적 라우팅 (0) | 2025.05.14 |
|---|---|
| Next.js - layout.tsx, children (0) | 2025.05.11 |
| Next.js, Redux - 로그인/로그아웃 (0) | 2025.05.06 |
| Redux login 예시 (0) | 2025.05.05 |
| getStaticProps, getStaticPaths (0) | 2025.04.26 |