728x90

nextjs nextauth를 활용해서 인증시스템을 구현하기 위한 가장 좋은 조합은?


Next.js와 NextAuth.js를 활용해 안정적이고 확장 가능한 인증 시스템을 구축하기 위한 최적의 조합은 다음과 같습니다. 각 레이어별 접근 방식을 조합해 보안, 성능, 유지보수성을 균형 있게 확보할 수 있습니다.

1. 미들웨어(Middleware): 전역 인증 검사
역할
모든 라우트 진입 전 인증 상태 확인: 사용자가 보호된 경로에 접근할 때마다 세션 유효성을 검사합니다.

기본 리디렉션 처리: 미인증 사용자를 로그인 페이지로 자동 이동시킵니다.

구현
typescript
// middleware.ts
import NextAuth from 'next-auth';
import { authConfig } from './auth.config';

export default NextAuth(authConfig).auth;

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],
};
typescript
// auth.config.ts
import type { NextAuthConfig } from 'next-auth';

export const authConfig = {
  pages: { signIn: '/login' },
  callbacks: {
    authorized({ auth, request }) {
      const isLoggedIn = !!auth?.user;
      const isProtectedRoute = request.nextUrl.pathname.startsWith('/dashboard');
      return isProtectedRoute ? isLoggedIn : true;
    },
  },
  providers: [], // OAuth 또는 Credentials 공급자 추가
} satisfies NextAuthConfig;
장점
성능 최적화: 라우트 렌더링 전에 차단하여 불필요한 작업 방지.

일관된 정책 적용: 모든 보호된 경로에 동일한 규칙 적용.

2. 서버 컴포넌트: 세부 권한 관리
역할
역할 기반 접근 제어(RBAC): 사용자 역할(admin, user)에 따라 콘텐츠 제한.

서버 측 데이터 페칭: 민감한 데이터를 클라이언트에 노출 없이 처리.

구현
typescript
// app/dashboard/page.tsx
import { getServerSession } from 'next-auth';
import { authOptions } from '@/app/api/auth/[...nextauth]/route';

export default async function Dashboard() {
  const session = await getServerSession(authOptions);
  
  if (!session?.user) redirect('/login');
  if (session.user.role !== 'admin') redirect('/unauthorized');

  const data = await fetchSensitiveData(); // 서버에서 직접 호출
  return <AdminContent data={data} />;
}
장점
SEO 친화적: 서버에서 완성된 HTML 제공.

보안 강화: 권한 검증을 서버에서 수행.

3. API 라우트: 백엔드 보호
역할
엔드포인트 보안 강화: 클라이언트-서버 통신 시 이중 검증.

데이터 무결성 보장: API 수준에서 인증/권한 확인.

구현
typescript
// app/api/admin/route.ts
import { getServerSession } from 'next-auth';
import { authOptions } from '../auth/[...nextauth]/route';

export async function GET() {
  const session = await getServerSession(authOptions);
  if (!session?.user || session.user.role !== 'admin') {
    return new Response('Unauthorized', { status: 401 });
  }
  return Response.json({ data: '관리자 전용 데이터' });
}
장점
무단 접근 차단: 직접 API 호출 시에도 보호.

유연한 에러 처리: 맞춤형 상태 코드 반환.

4. 클라이언트 컴포넌트: 실시간 UX
역할
동적 UI 업데이트: 로그인 상태에 따른 버튼/메뉴 변경.

로딩 상태 표시: 사용자에게 진행 상황 피드백.

구현
typescript
'use client';
// components/UserMenu.tsx
import { useSession } from 'next-auth/react';

export default function UserMenu() {
  const { data: session, status } = useSession();

  if (status === 'loading') return <Skeleton />;
  return session ? <ProfileMenu user={session.user} /> : <LoginButton />;
}
장점
사용자 경험 개선: 즉각적인 UI 반응.

세션 동기화: 탭 간 상태 일관성 유지.

5. NextAuth.js 설정: 확장성 확보
권장 구성
typescript
// auth.config.ts
import NextAuth from 'next-auth';
import Google from 'next-auth/providers/google';
import Credentials from 'next-auth/providers/credentials';

export const authOptions = {
  providers: [
    Google({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    Credentials({
      async authorize(credentials) {
        // 커스텀 로그인 로직 (예: 이메일/비밀번호)
      },
    }),
  ],
  callbacks: {
    async jwt({ token, user }) {
      if (user) token.role = user.role; // 역할 정보 추가
      return token;
    },
    async session({ session, token }) {
      session.user.role = token.role; // 클라이언트에 역할 전달
      return session;
    },
  },
};
보안 강화 설정
Cookie 옵션: Secure, HttpOnly, SameSite=Strict 적용.

세션 갱신: updateAge: 24 * 60 * 60 (24시간마다 갱신).

종합 비교 및 권장 조합
방법 사용 사례 보안 성능 구현 복잡도
미들웨어 전역 인증 검사 ⭐⭐⭐ ⭐⭐⭐ 낮음
서버 컴포넌트 역할 기반 접근 제어, SEO 최적화 ⭐⭐⭐ ⭐⭐⭐ 중간
API 라우트 백엔드 API 보호 ⭐⭐⭐ ⭐⭐ 중간
클라이언트 실시간 UI 업데이트 ⭐ ⭐⭐ 낮음
최적화 조합 전략
미들웨어로 기본 인증 검사 → 서버 컴포넌트에서 세부 권한 확인 → API 라우트에서 이중 검증.

클라이언트 컴포넌트는 보조적 UI 업데이트용으로만 사용.

NextAuth.js 설정: JWT + 세션 콜백으로 역할 정보 확장.

보안 추가 권장 사항
HTTPS 강제: next.config.js에서 HTTPS 리디렉션 설정.

환경 변수 관리: NEXTAUTH_SECRET 반드시 설정.

로그인 시도 제한: IP 기반 차단 또는 CAPTCHA 통합.

2FA(이중 인증): 중요한 기능에 대해 추가 인증 계층 적용.

이 조합을 통해 Next.js 애플리케이션의 인증 시스템을 견고하게 구축할 수 있으며, 확장성과 유지보수성도 함께 확보됩니다.

+ Recent posts