[Next.js] 미들웨어(Middleware)를 활용한 페이지 접근 통제




아래 글에 이어서 미들웨어(Middleware)를 이용하여 페이지 접근통제를 적용하는 내용을 정리합니다.


지난 포스트


미들웨어(Middleware) 란?

Next.js의 미들웨어는 매우 강력한 기능으로, 서버나 클라이언트 사이드에서 실행되는 코드입니다. 이 미들웨어는 사용자의 요청이 서버에 도달하고 최종 페이지나 API 라우트에 의해 처리되기 전에 특정 조건을 검사하거나 사전 처리를 수행할 수 있게 해줍니다.

미들웨어의 기능

미들웨어는 다음과 같은 다양한 기능을 수행할 수 있습니다:

  1. 인증 및 권한 부여: 사용자가 특정 페이지에 접근하기 전에 로그인 상태를 확인하거나, 해당 사용자가 접근 권한을 가지고 있는지 확인합니다.
  2. 리다이렉션: 사용자를 다른 페이지로 리다이렉션 할 수 있습니다. 예를 들어, 로그인하지 않은 사용자를 로그인 페이지로 보내거나, 특정 조건에 따라 사용자를 관련 페이지로 안내할 수 있습니다.
  3. 요청 수정: 요청에 헤더를 추가하거나 요청을 조작하여 API 또는 다음 처리 단계에 전달하기 전에 변경할 수 있습니다.
  4. 로그 및 모니터링: 모든 요청에 대해 로깅을 수행하거나, 특정 데이터를 모니터링하고 분석할 수 있습니다.

코드 작성

디렉토리 구조

프로젝트의 디렉토리 구조는 다음과 같습니다.

/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 접속




Leave a Comment