Communitygithub.com

Auth.js (NextAuth v5) 패턴

Auth.js (NextAuth v5) 인증 패턴 - 설정, 프로바이더, 세션 전략, 미들웨어, 데이터베이스 어댑터, 역할 기반 접근, Edge 호환성

Auth.js (NextAuth v5) 패턴란 무엇인가요?

이 스킬은 Next.js, SvelteKit, Express 등 다양한 프레임워크에서 Auth.js (NextAuth v5)를 사용하여 인증을 구현하는 방법을 상세히 안내합니다. 루트 `auth.ts` 파일에 통합 설정을 하고 `{ auth, handlers, signIn, signOut }`을 export하는 것이 핵심이며, 서버 컴포넌트, 라우트 핸들러, 서버 액션, 미들웨어 등 모든 서버 사이드 컨텍스트에서 단일 `auth()` 함수를 사용해야 합니다. OAuth, Credentials, 이메일/매직 링크 등 다양한 프로바이더를 지원하며, JWT(기본) 또는 데이터베이스 기반 세션 전략을 선택할 수 있습니다. 또한 미들웨어를 통한 경로 보호, Prisma/Drizzle 어댑터를 이용한 데이터베이스 연동, jwt/session 콜백을 통한 세션 커스터마이징, Edge 런타임 호환성을 위한 설정 분리 등 실무에 필요한 패턴을 포괄적으로 다룹니다. 더 이상 사용되지 않는 `getServerSession()`, `NEXTAUTH_SECRET`과 같은 구버전 패턴을 사용하지 않도록 주의해야 합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/agents-inc/skills/tree/HEAD/src/skills/api-auth-nextauth

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Auth.js (NextAuth v5) 패턴은(는) 무엇을 하나요?

빠른 가이드: 루트 auth.ts 파일에 Auth.js를 설정하고 NextAuth()에서 { auth, handlers, signIn, signOut }을 export합니다. 모든 곳(서버 컴포넌트, 라우트 핸들러, 미들웨어)에서 통합 auth() 함수를 사용합니다. 기본 세션 전략은 JWT(쿠키 기반)이며, 지속적인 세션을 위해 데이터베이스 어댑터를 추가합니다. 미들웨어 또는 페이지별 auth() 검사를 통해 경로를 보호합니다.


<critical_requirements>

중요: 이 스킬을 사용하기 전에

모든 코드는 CLAUDE.md의 프로젝트 규칙을 따라야 합니다 (kebab-case, named export, import 순서, import type, 명명된 상수)

(루트 auth.ts 파일에 Auth.js를 설정하고 NextAuth()에서 { auth, handlers, signIn, signOut }을 export해야 합니다)

(서버 측 세션 접근에 통합 auth() 함수를 사용해야 합니다 - 더 이상 사용되지 않는 getServerSession(), getSession(), 또는 getToken()을 사용하지 마세요)

(AUTH_SECRET 환경 변수를 사용해야 합니다 - NEXTAUTH_SECRET은 v5에서 더 이상 사용되지 않습니다)

(프로바이더 자격 증명에는 AUTH_ 접두사가 붙은 환경 변수를 사용해야 합니다 (예: AUTH_GITHUB_ID, AUTH_GITHUB_SECRET) - 자동으로 감지됩니다)

(데이터베이스 세션을 미들웨어와 함께 사용하는 경우 인증 설정을 auth.config.ts(Edge 호환)와 auth.ts(어댑터 포함)로 분할해야 합니다)

(서버 액션과 API 라우트 내에서 세션을 반드시 확인해야 합니다 - 미들웨어만으로는 인증에 충분하지 않습니다)

</critical_requirements>


자동 감지: Auth.js, NextAuth, next-auth, authjs, auth.ts, auth.config.ts, NextAuth(), signIn, signOut, auth(), handlers, SessionProvider, useSession, AUTH_SECRET, OAuth 프로바이더, credentials 프로바이더, 데이터베이스 어댑터, @auth/prisma-adapter, @auth/drizzle-adapter, authorized 콜백, jwt 콜백, session 콜백, 프록시 auth, 미들웨어 auth

사용 시기:

  • Next.js, SvelteKit, Express, Qwik 앱에 인증 추가
  • 80개 이상의 내장 프로바이더로 OAuth 로그인 구현 (GitHub, Google, Discord 등)
  • 이메일/매직 링크 인증 흐름 구축
  • JWT 또는 데이터베이스 기반 세션 관리 필요
  • Edge 호환 미들웨어 인증이 필요한 프로젝트

사용하지 말아야 할 시기:

  • 처음부터 커스텀 인증 시스템 구축 (Auth.js는 정해진 방식이 있습니다)
  • 즉시 사용 가능한 세분화된 조직/팀 관리가 필요
  • 웹 프론트엔드 없는 모바일 전용 앱
  • 플러그인 아키텍처로 자체 호스팅 인증이 필요

주요 패턴:

  • 인증 설정 (auth.ts, auth.config.ts)
  • OAuth 프로바이더 (GitHub, Google, Credentials, Email)
  • 세션 전략 (JWT vs 데이터베이스)
  • 세션 접근 (서버 컴포넌트, 라우트 핸들러, 클라이언트 컴포넌트)
  • 미들웨어/프록시 경로 보호
  • 데이터베이스 어댑터 (Prisma, Drizzle)
  • 콜백 (jwt, session, signIn, redirect)
  • 역할 기반 접근 제어
  • Edge 호환성 분할 설정

상세 자료:

  • 의사 결정 프레임워크 및 안티 패턴: reference.md 참조

핵심 패턴:


철학

Auth.js (v5)는 인증을 단일 통합 API로 통합합니다. auth() 함수는 v4의 getServerSession, getSession, withAuth, getToken을 서버 측에서 대체합니다. useSession()은 여전히 올바른 클라이언트 측 API입니다. 설정은 API 라우트가 아닌 루트 파일에 위치합니다.

핵심 원칙:

  1. 프레임워크에 구애받지 않음 - Next.js, SvelteKit, Express, Qwik과 함께 작동
  2. 통합 API - 모든 서버 측 컨텍스트를 위한 단일 auth() 함수
  3. 프로바이더 생태계 - 80개 이상의 내장 OAuth 프로바이더, AUTH_* 환경 변수 자동 감지
  4. 기본 JWT - 암호화된 쿠키의 무상태 세션, 데이터베이스 불필요
  5. Edge 호환 - 미들웨어는 Edge 런타임에서 실행 (Next.js 16 프록시는 Node.js에서 실행)
  6. 점진적 복잡성 - OAuth로 시작하고, 데이터베이스 어댑터를 추가한 다음 콜백을 커스터마이징

핵심 패턴

패턴 1: 인증 설정

중앙 설정 파일은 NextAuth()에서 필요한 모든 것을 export합니다.

기본 OAuth 설정

// auth.ts
import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";
import Google from "next-auth/providers/google";

export const { auth, handlers, signIn, signOut } = NextAuth({
  providers: [
    GitHub, // AUTH_GITHUB_ID 및 AUTH_GITHUB_SECRET 자동 감지
    Google, // AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET 자동 감지
  ],
});
// app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth";

export const { GET, POST } = handlers;

이점: 단일 설정 파일이 모든 인증 유틸리티를 export하고, 프로바이더가 AUTH_* 환경 변수를 자동 감지하며, API 라우트가 최소화됨

환경 변수

# .env.local
AUTH_SECRET="npx-auth-secret으로-생성"  # 필수
AUTH_GITHUB_ID="your-github-client-id"       # GitHub 프로바이더가 자동 감지
AUTH_GITHUB_SECRET="your-github-secret"      # GitHub 프로바이더가 자동 감지
AUTH_GOOGLE_ID="your-google-id"       # Google 프로바이더가 자동 감지
AUTH_GOOGLE_SECRET="your-google-secret"

이점: v5에서 AUTH_ 접두사가 표준화되었고, AUTH_SECRET이 더 이상 사용되지 않는 NEXTAUTH_SECRET을 대체하며, 프로바이더가 자격 증명을 자동 감지함


패턴 2: 프로바이더

Auth.js는 OAuth, 이메일/매직 링크, 자격 증명 인증을 지원합니다. 80개 이상의 내장 OAuth 프로바이더가 AUTH_* 환경 변수를 자동 감지합니다.

// OAuth: 프로필 매핑 커스터마이징
GitHub({
  profile(profile) {
    return {
      id: String(profile.id),
      name: profile.name ?? profile.login,
      role: "user",
    };
  },
});

// Credentials: 입력 유효성 검사, 실패 시 null 반환
Credentials({
  async authorize(credentials) {
    const parsed = LoginSchema.safeParse(credentials);
    if (!parsed.success) return null;
    const user = await getUserByEmail(parsed.data.email);
    if (
      !user ||
      !(await verifyPassword(parsed.data.password, user.hashedPassword))
    )
      return null;
    return { id: user.id, name: user.name, email: user.email };
  },
});

핵심 규칙: DB 조회 전에 입력 유효성 검사, 항상 비밀번호 해싱, 실패 시 null 반환 (절대 throw하지 마세요 - 정보가 유출됩니다). 전체 구현은 examples/core.md를 참조하세요.


패턴 3: 콜백

네 가지 콜백이 인증 동작을 커스터마이징합니다. 데이터 흐름: jwt 콜백 (토큰 강화) -> session 콜백 (클라이언트에 노출).

callbacks: {
  jwt({ token, user }) {
    if (user) { token.id = user.id; token.role = user.role ?? "user"; }
    return token;
  },
  session({ session, token }) {
    session.user.id = token.id as string;
    session.user.role = token.role as string;
    return session;
  },
}

핵심 규칙: JWT 콜백은 모든 auth() 호출 시 실행되므로 가볍게 유지, user 매개변수는 로그인 시에만 존재, OAuth 토큰을 클라이언트에 절대 노출하지 마세요. signIn 및 redirect를 포함한 전체 콜백 구현은 examples/core.md를 참조하세요.


패턴 4: 세션 접근

통합 auth() 함수는 v4의 getServerSession, getSession, getToken을 서버 측에서 대체합니다. useSession()은 클라이언트 컴포넌트용으로 유지됩니다.

컨텍스트세션 접근 방법
서버 컴포넌트const session = await auth()
라우트 핸들러export const GET = auth(function GET(req) { req.auth })
서버 액션const session = await auth()
미들웨어/프록시export { auth as middleware } 또는 authorized 콜백
클라이언트 컴포넌트useSession() (레이아웃에 SessionProvider 필요)

핵심 규칙: 서버 측 임포트는 @/auth에서, 클라이언트 측 임포트는 next-auth/react에서 가져옵니다. 클라이언트 컴포넌트에서 auth()를 호출하지 마세요. 전체 구현은 examples/session.md를 참조하세요.


패턴 5: 로그인 / 로그아웃 액션

두 가지 접근 방식: 서버 액션 (권장, 점진적 향상) 또는 클라이언트 측.

// 서버 측 (권장): @/auth에서 임포트, 폼에서 서버 액션 사용
import { signIn, signOut } from "@/auth";
// 폼 액션 내: await signIn("github", { redirectTo: "/dashboard" })
// 폼 액션 내: await signOut({ redirectTo: "/" })

// 클라이언트 측: next-auth/react에서 임포트, onClick 핸들러 사용
import { signIn, signOut } from "next-auth/react";
// onClick: signIn("github", { callbackUrl: "/dashboard" })

핵심 규칙: 서버 측은 redirectTo, 클라이언트 측은 callbackUrl을 사용합니다. signIn()은 내부적으로 NEXT_REDIRECT 예외를 throw합니다. 반환 값을 기대하며 try/catch로 감싸지 마세요. 전체 구현은 examples/core.md를 참조하세요.


패턴 6: TypeScript 확장

types/next-auth.d.ts에서 선언 병합을 통해 세션 및 JWT 타입을 확장합니다. Session, User, JWT 인터페이스에 커스텀 필드 (예: id, role)를 & DefaultSession["user"]와 함께 선언하여 기본값을 유지합니다. 전체 타입 선언 예제는 examples/core.md를 참조하세요.


통합 가이드

Auth.js는 인증 계층입니다. 신원 확인, 세션 관리, 경로 보호를 처리합니다. 권한 부여 로직 (역할 확인, 권한 시스템)은 처리하지 않습니다. 이는 애플리케이션 코드의 영역입니다.

프레임워크 지원: Auth.js는 프레임워크별 패키지 (next-auth, @auth/sveltekit, @auth/express)를 통해 여러 웹 프레임워크와 함께 작동합니다.

데이터베이스 어댑터: 데이터베이스 세션의 경우 Auth.js는 ORM과 통합되는 어댑터 패키지 (@auth/prisma-adapter, @auth/drizzle-adapter 등)를 제공합니다. examples/database.md를 참조하세요.

세션 전략은 필요에 따라 선택합니다:

  • JWT (기본) - 데이터베이스 불필요, Edge에서 작동, 무상태
  • 데이터베이스 - 어댑터 필요, 서버 측 세션 저장소, 즉시 해지 지원

Auth.js가 처리하지 않는 것: 세분화된 권한 부여/RBAC, 속도 제한, 인증 외 데이터베이스 쿼리 - 이는 애플리케이션 수준의 문제입니다.


<red_flags>

주의 사항

  • getServerSession(authOptions) 사용 -- v5에서 더 이상 사용되지 않음; auth.ts의 auth()를 사용하세요.
  • NEXTAUTH_SECRET 또는 NEXTAUTH_URL 사용 -- 더 이상 사용되지 않음; AUTH_SECRET을 사용하세요. (URL은 자동 감지됨)
  • 속도 제한 없는 Credentials 프로바이더 -- 무차별 대입 공격에 취약합니다.
  • session 콜백을 통해 클라이언트에 OAuth 토큰 노출 -- accessToken/refreshToken은 서버 측에서만 유지하세요.
  • 미들웨어/프록시를 유일한 인증 수단으로 사용 -- 렌더링 전에 실행되지만 서버 액션/API 라우트의 경로별 검사를 대체하지는 않습니다.
  • 미들웨어에서 데이터베이스 어댑터 임포트 -- 데이터베이스 ORM은 Edge 런타임에서 실행될 수 없습니다 (Next.js 14/15); 설정을 auth.config.ts + auth.ts로 분할하세요.
  • signIn()을 try/catch로 감싸기 -- 내부적으로 NEXT_REDIRECT 예외를 throw합니다. (의도된 동작입니다)
  • JWT 콜백이 매 호출마다 데이터베이스 쿼리 -- 모든 auth() 호출 시 실행되므로 가볍게 유지하세요.

전체 안티 패턴 목록, 주의사항 및 마이그레이션 테이블은 reference.md를 참조하세요.

</red_flags>


<critical_reminders>

중요 알림

모든 코드는 CLAUDE.md의 프로젝트 규칙을 따라야 합니다

(루트 auth.ts 파일에 Auth.js를 설정하고 NextAuth()에서 { auth, handlers, signIn, signOut }을 export해야 합니다)

(서버 측 세션 접근에 통합 auth() 함수를 사용해야 합니다 - 더 이상 사용되지 않는 getServerSession(), getSession(), 또는 getToken()을 사용하지 마세요)

(AUTH_SECRET 환경 변수를 사용해야 합니다 - NEXTAUTH_SECRET은 v5에서 더 이상 사용되지 않습니다)

(프로바이더 자격 증명에는 AUTH_ 접두사가 붙은 환경 변수를 사용해야 합니다 (예: AUTH_GITHUB_ID, AUTH_GITHUB_SECRET) - 자동으로 감지됩니다)

(데이터베이스 세션을 미들웨어와 함께 사용하는 경우 인증 설정을 auth.config.ts(Edge 호환)와 auth.ts(어댑터 포함)로 분할해야 합니다)

(서버 액션과 API 라우트 내에서 세션을 반드시 확인해야 합니다 - 미들웨어만으로는 인증에 충분하지 않습니다)

이 규칙을 따르지 않으면 인증 실패, 더 이상 사용되지 않는 패턴 노출 또는 보안 취약점이 발생할 수 있습니다.

</critical_reminders>

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

관련 스킬