아래 글에 이어서 미들웨어(Middleware)를 이용하여 페이지 접근통제를 적용하는 내용을 정리합니다.
지난 포스트
미들웨어(Middleware) 란?
Next.js의 미들웨어는 매우 강력한 기능으로, 서버나 클라이언트 사이드에서 실행되는 코드입니다. 이 미들웨어는 사용자의 요청이 서버에 도달하고 최종 페이지나 API 라우트에 의해 처리되기 전에 특정 조건을 검사하거나 사전 처리를 수행할 수 있게 해줍니다.
미들웨어의 기능
미들웨어는 다음과 같은 다양한 기능을 수행할 수 있습니다:
- 인증 및 권한 부여: 사용자가 특정 페이지에 접근하기 전에 로그인 상태를 확인하거나, 해당 사용자가 접근 권한을 가지고 있는지 확인합니다.
- 리다이렉션: 사용자를 다른 페이지로 리다이렉션 할 수 있습니다. 예를 들어, 로그인하지 않은 사용자를 로그인 페이지로 보내거나, 특정 조건에 따라 사용자를 관련 페이지로 안내할 수 있습니다.
- 요청 수정: 요청에 헤더를 추가하거나 요청을 조작하여 API 또는 다음 처리 단계에 전달하기 전에 변경할 수 있습니다.
- 로그 및 모니터링: 모든 요청에 대해 로깅을 수행하거나, 특정 데이터를 모니터링하고 분석할 수 있습니다.
코드 작성
디렉토리 구조
프로젝트의 디렉토리 구조는 다음과 같습니다.
/app
├── /api
│ └── /auth
│ └── [...nextauth]
│ └── route.ts // NextAuth 설정 파일
│ └── signup
│ └── route.ts // 회원 가입 API
├── /auth
│ └── signin
│ └── page.tsx // 로그인 페이지
│ └── signup
│ └── page.tsx // 회원 가입 페이지
├── /admin
│ └── page.tsx // 관리자 페이지
│ └── home
│ └── page.tsx // 관리자 홈 페이지
├── /lib
│ └── db.ts // PostgreSQL 연결 설정
├── /public
│ └── page.tsx // 공개 페이지
├── /layout.tsx // 전역 레이아웃
└── /page.tsx // 메인 페이지
/middleware.ts // 미들웨어 설정
/.env // 환경 설정
1. /middleware.ts
추가
미들웨어 기능을 사용하기 위하여 디렉토리 최상단에 미들웨어 코드를 추가합니다.
import { NextRequest, NextResponse } from 'next/server';
import { getToken } from 'next-auth/jwt';
export async function middleware(req: NextRequest) {
const secret = process.env.NEXTAUTH_SECRET;
const token = await getToken({ req, secret });
// 로그를 추가하여 요청을 확인
console.log('Accessing:', req.nextUrl.pathname, 'Token exists:', !!token);
if (!token && req.nextUrl.pathname.startsWith('/admin')) {
const url = req.nextUrl.clone();
url.pathname = '/auth/signin';
return NextResponse.redirect(url);
}
return NextResponse.next();
}
2. /app/admin/page.tsx
수정
기존 admin 페이지에서 session 체크하는 부분을 제거합니다.
'use client';
import { useSession } from 'next-auth/react';
export default function AdminPage() {
const { data: session, status } = useSession();
if (status === 'loading') {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-100">
<p className="text-xl text-gray-600">Loading...</p>
</div>
);
}
return (
<div className="min-h-screen flex flex-col items-center justify-center bg-gray-100">
<div className="bg-white p-8 rounded-lg shadow-md w-full max-w-lg text-center">
<h1 className="text-3xl font-bold mb-4 text-gray-800">Admin Dashboard</h1>
<p className="text-lg text-gray-600">
Welcome, {session.user?.email}! You have admin access.
</p>
</div>
</div>
);
}
3. /app/admin/home/page.tsx
추가
하위 페이지 접근 통제 여부 테스트를 위하여 admin 하위에 home 페이지를 추가합니다.
'use client';
import { useSession } from 'next-auth/react';
export default function AdminHomePage() {
const { data: session, status } = useSession();
if (status === 'loading') {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-100">
<p className="text-xl text-gray-600">Loading...</p>
</div>
);
}
return (
<div className="min-h-screen flex flex-col items-center justify-center bg-gray-100">
<div className="bg-white p-8 rounded-lg shadow-md w-full max-w-lg text-center">
<h1 className="text-3xl font-bold mb-4 text-gray-800">Admin Home Dashboard</h1>
<p className="text-lg text-gray-600">
Welcome, {session.user?.email}! You have admin access.
</p>
</div>
</div>
);
}
마치며
Next.js 미들웨어를 활용하면 서버 사이드에서 효율적으로 접근 통제 로직을 구현할 수 있습니다. 이를 통해 애플리케이션의 보안을 강화하고, 필요에 따라 사용자의 접근을 세밀하게 관리할 수 있습니다. Next.js 미들웨어는 모던 웹 개발에서 중요한 도구 중 하나로 자리 잡고 있습니다.
테스트
최초 화면

Admin Page, Admin Home Page 접속
admin 페이지와 home 페이지를 접속하면 로그인이 안 되어 있기 때문에 login 페이지로 redirect 됩니다.

로그인

Admin Page 재 접속

Admin 하위 Home Page 접속
