본문 바로가기
C.W.K.
Stream
Lesson 04 of 09 · published

Auth.js v5의 단일 auth() 모델

~22 min · Auth.js, OAuth, session

Level 0호기심
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

어디서 묻든 같은 방식으로 세션을 읽어

Auth.js v5, 예전 이름으로 NextAuth.js는 서버 컴포넌트, 서버 액션, 라우트 핸들러, Proxy에서 모두 쓸 수 있는 auth() 도우미를 제공해. “현재 세션이 있는가?”라는 질문을 실행 위치마다 다른 API로 번역하지 않아도 돼.

설정과 HTTP 엔드포인트를 연결해

next-auth@beta를 설치하고 provider를 구성한 뒤 handlersauth를 내보내. handlersapp/api/auth/[...nextauth]/route.ts에서 라우트 핸들러로 연결해 인증 callback URL을 제공해.

위치호출 방식
서버 컴포넌트const session = await auth()
서버 액션const session = await auth()
라우트 핸들러const session = await auth()
Proxyexport const proxy = auth(req => { ... })

세션 존재와 자원 권한을 구분해

로그인했다는 사실만으로 모든 글과 조직을 수정할 수 있는 건 아니야. auth()로 신원을 확인한 뒤, 실제 변경 지점에서 대상 자원의 소유권이나 역할을 다시 검사해.

auth() 호출을 공통 helper로 감싸 익명 허용, 로그인 필수, 특정 역할 필요 같은 정책을 이름으로 드러내. 서버 컴포넌트는 표시할 데이터 전에, 액션과 핸들러는 쓰기 직전에 호출해. 세션이 오래됐을 때 provider와 DB의 역할 정보가 어떻게 갱신되는지도 정해. 인증 확인을 공통 도우미로 모아도 각 실행 위치의 실패 응답은 따로 설계해야 해. 페이지 이동, API 호출, 서버 액션이 모두 같은 방식으로 로그인 화면만 반환하면 클라이언트 계약이 깨질 수 있어.

어디서나 같은 helper를 부를 수 있다는 장점이 모든 곳에서 같은 결정을 한다는 뜻은 아니야. 페이지 열람과 조직 삭제는 요구하는 신뢰 수준이 다르지. 인증 도구는 사용자를 식별하고, 앱의 권한 계층은 각 행동을 허용할지 결정해야 해. 서버 컴포넌트·액션·라우트 핸들러·Proxy 네 자리에서 같은 계정으로 auth() 결과를 확인해. 세션 없음·만료·역할 변경을 각각 시험하고, 로그인 상태는 통과하지만 다른 조직 자원은 최종 쓰기 경계에서 거부되는지 확인해.

Code

auth.ts — 하나의 설정 파일·ts
// auth.ts
import NextAuth from 'next-auth';
import GitHub from 'next-auth/providers/github';
import Google from 'next-auth/providers/google';

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [
    GitHub({ clientId: process.env.GITHUB_ID!, clientSecret: process.env.GITHUB_SECRET! }),
    Google({ clientId: process.env.GOOGLE_ID!, clientSecret: process.env.GOOGLE_SECRET! }),
  ],
});
핸들러를 연결한 뒤 어디서나 auth() 호출하기·ts
// app/api/auth/[...nextauth]/route.ts
export { GET, POST } from '@/auth';

// 서버 컴포넌트 안:
import { auth } from '@/auth';
export default async function Page() {
  const session = await auth();
  return session ? <p>Welcome {session.user?.name}</p> : <SignInButton />;
}

// 서버 액션 안:
export async function createPost() {
  'use server';
  const session = await auth();
  if (!session) throw new Error('Unauthorized');
  // …
}

// proxy.ts 안:
import { auth } from '@/auth';
import { NextResponse } from 'next/server';

export const proxy = auth((req) => {
  if (!req.auth && req.nextUrl.pathname.startsWith('/app')) {
    return NextResponse.redirect(new URL('/login', req.url));
  }
});

External links

Exercise

서버 컴포넌트, 서버 액션, 라우트 핸들러, Proxy에서 같은 계정의 auth() 결과를 확인해. 세션 만료와 다른 조직 자원도 시험해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.