Next.js에서의 인증 전략과 쿠키 vs 토큰

2026. 5. 10. 14:51·Next.js

Next.js에서 인증이 중요한 이유

Next.js에서 인증이 조금 까다롭게 느껴지는 이유는 단순히 “로그인 여부를 확인하는 코드”만 작성하면 끝나는 구조가 아니기 때문입니다.

 

Next.js는 Server Components, Client Components, Route Handlers, Server Actions, Proxy 등 여러 실행 지점을 가지고 있고, 각각의 코드가 실행되는 위치가 다릅니다. 어떤 코드는 서버에서만 실행되고, 어떤 코드는 브라우저에서 실행되며, 어떤 코드는 사용자의 요청이 페이지에 도달하기 전에 먼저 실행됩니다.

 

그래서 Next.js에서 인증을 설계할 때는 “로그인 상태를 어디에 저장할 것인가”, “서버 컴포넌트에서 세션을 어떻게 읽을 것인가”, “클라이언트 컴포넌트에서는 사용자 정보를 어떻게 사용할 것인가”, “보호된 페이지 접근은 어디서 막을 것인가”를 함께 고민해야 합니다. Next.js 공식 문서에서도 인증을 단순 로그인 구현이 아니라 인증, 세션 관리, 인가라는 흐름으로 나누어 설명합니다.

 

일반적인 React SPA에서는 로그인 후 accessToken을 localStorage나 메모리에 저장하고, API 요청 시 Authorization 헤더에 붙이는 방식이 자주 사용됩니다.

 

하지만 Next.js에서는 서버에서 먼저 렌더링되는 영역이 많기 때문에 브라우저 저장소에만 의존하면 서버 컴포넌트에서 인증 정보를 바로 알기 어렵습니다. 예를 들어 localStorage는 브라우저에서만 접근할 수 있으므로 Server Component, Route Handler, Server Action에서는 직접 사용할 수 없습니다.

 

이 때문에 Next.js에서는 쿠키 기반 세션 관리가 자주 사용됩니다. 쿠키는 브라우저가 요청을 보낼 때 자동으로 함께 전송되기 때문에 서버에서도 인증 상태를 확인하기 쉽습니다. 특히 httpOnly 쿠키를 사용하면 클라이언트 JavaScript에서 쿠키 값을 직접 읽을 수 없어서 XSS 공격으로 토큰이 탈취될 가능성을 줄일 수 있습니다.

쿠키 기반 인증과 JWT 토큰 기반 인증

쿠키 기반 인증은 사용자의 인증 상태를 쿠키에 저장하고, 이후 요청마다 브라우저가 쿠키를 자동으로 서버에 전달하는 방식입니다. 보통 서버는 쿠키에 담긴 세션 ID나 세션 토큰을 확인한 뒤, 해당 사용자가 로그인한 사용자인지 판단합니다. 이때 쿠키에 httpOnly, Secure, SameSite 같은 옵션을 설정하는 것이 중요합니다.

 

httpOnly는 브라우저의 JavaScript에서 쿠키에 접근하지 못하게 하는 옵션입니다. 이 옵션을 사용하면 document.cookie로 쿠키 값을 읽을 수 없기 때문에, XSS 취약점이 발생하더라도 토큰 자체가 직접 탈취될 가능성을 낮출 수 있습니다. Secure는 HTTPS 환경에서만 쿠키가 전송되도록 제한하는 옵션이고, SameSite는 다른 사이트에서 발생한 요청에 쿠키를 함께 보낼지 제어하는 옵션입니다. SameSite=Lax 또는 Strict를 사용하면 CSRF 공격 가능성을 줄이는 데 도움이 됩니다.

 

JWT 기반 인증은 로그인 성공 시 서버가 JWT를 발급하고, 클라이언트가 이 토큰을 보관한 뒤 API 요청마다 Authorization 헤더에 넣어 보내는 방식입니다. JWT는 자체적으로 사용자 식별 정보와 만료 시간 등을 포함할 수 있기 때문에 서버가 매 요청마다 세션 저장소를 조회하지 않아도 되는 장점이 있습니다. 다만 JWT를 어디에 저장하느냐가 중요합니다.

 

JWT를 localStorage에 저장하면 구현은 간단하지만 XSS에 취약해질 수 있습니다. 공격자가 클라이언트 JavaScript 실행 권한을 얻으면 localStorage에 저장된 토큰을 읽어갈 수 있기 때문입니다. 반대로 JWT를 httpOnly 쿠키에 저장하면 JavaScript에서 직접 읽을 수 없기 때문에 XSS로 인한 토큰 탈취 위험은 줄어듭니다. 다만 쿠키는 요청에 자동 포함되기 때문에 CSRF 방어를 함께 고려해야 합니다.

 

즉, JWT 자체가 위험하다기보다는 JWT를 저장하고 전송하는 방식에 따라 보안 특성이 달라집니다. localStorage 기반 JWT는 클라이언트 중심 SPA에서 구현하기 쉽지만 XSS에 더 민감하고, httpOnly 쿠키 기반 JWT 또는 세션 토큰 방식은 서버 중심 렌더링과 잘 맞지만 CSRF 방어와 쿠키 설정을 신경 써야 합니다.

Next.js에서 쿠키 기반 인증이 자주 권장되는 이유

Next.js에서는 서버에서 인증 정보를 읽어야 하는 상황이 많습니다. Server Component에서 사용자 정보를 기반으로 다른 UI를 보여줘야 할 수 있고, Server Action에서 사용자의 권한을 확인해야 할 수도 있으며, Route Handler에서 요청을 처리하기 전에 세션을 검증해야 할 수도 있습니다.

 

이때 쿠키 기반 인증은 Next.js의 구조와 잘 맞습니다. 브라우저가 요청을 보낼 때 쿠키를 자동으로 포함하므로 서버는 요청 객체에서 쿠키를 읽어 현재 사용자를 확인할 수 있습니다. 반면 localStorage에 저장된 토큰은 서버에서 직접 읽을 수 없기 때문에, 서버 렌더링 단계에서는 인증 상태를 알기 어렵습니다.

 

또한 Next.js App Router에서는 서버 컴포넌트를 통해 데이터 페칭과 렌더링을 서버에서 처리하는 경우가 많습니다. 이 구조에서는 인증 정보도 서버에서 안전하게 확인하는 편이 자연스럽습니다. 예를 들어 /dashboard 페이지에 접근했을 때 서버에서 세션을 확인하고, 로그인하지 않은 사용자는 로그인 페이지로 리다이렉트하는 흐름을 만들 수 있습니다.

 

다만 쿠키 기반 인증이 항상 정답이라는 의미는 아닙니다. 서비스 구조, 백엔드 API 구조, 모바일 앱 연동 여부, 서브도메인 구성, 외부 API 호출 방식에 따라 JWT 헤더 기반 인증이 더 편한 경우도 있습니다. 중요한 것은 Next.js에서는 서버와 클라이언트가 함께 동작하므로, 클라이언트 저장소에만 인증 상태를 두는 방식은 제한이 있다는 점입니다.

 

구분 쿠키 기반 인증 JWT 토큰 기반 인증

저장 위치 주로 httpOnly 쿠키 localStorage, sessionStorage, memory, cookie 등
서버 컴포넌트 접근 요청 쿠키를 통해 접근하기 쉬움 localStorage 저장 시 서버에서 직접 접근 어려움
XSS 대응 httpOnly 설정 시 토큰 직접 탈취 위험 감소 localStorage 저장 시 XSS에 취약
CSRF 대응 쿠키 자동 전송 때문에 SameSite, CSRF 토큰 고려 필요 Authorization 헤더 방식이면 CSRF 위험이 상대적으로 낮음
구현 난이도 쿠키 옵션과 서버 세션 처리 필요 API 요청 헤더 처리 중심으로 구현 가능
Next.js와의 궁합 Server Component, Route Handler, Server Action과 잘 맞음 클라이언트 중심 구조에서는 편하지만 서버 렌더링과 연결 시 추가 설계 필요
적합한 경우 SSR, 서버 중심 인증, 보안 중심 웹 서비스 SPA, 외부 API 연동, 모바일 앱과 토큰 공유가 필요한 경우

Better Auth와 Auth.js v5

Better Auth와 Auth.js는 둘 다 웹 서비스에서 로그인, 회원가입, 세션 관리, 소셜 로그인, 권한 처리 등을 쉽게 구현하기 위한 인증 라이브러리입니다. 다만 지향점과 사용감이 조금 다릅니다.

Better Auth

Better Auth는 TypeScript 기반의 인증·인가 프레임워크입니다. 공식 문서에서는 특정 프레임워크에 묶이지 않는 “framework-agnostic” 인증 프레임워크라고 설명합니다. Next.js뿐 아니라 여러 JavaScript/TypeScript 환경에서 사용할 수 있고, 이메일/비밀번호 로그인, 세션 관리, 2FA, 패스키, 멀티 세션, 멀티 테넌시 같은 기능을 플러그인 중심으로 확장할 수 있습니다.

 

쉽게 말하면 Better Auth는 “인증 기능을 내 애플리케이션 안에 직접 구성하는 도구”에 가깝습니다. Clerk, Auth0처럼 외부 인증 서비스를 붙이는 느낌보다는, 내 프로젝트 안에서 인증 서버 로직과 클라이언트 사용 방식을 함께 구성하는 방식입니다.

 

Better Auth의 강점은 기능 확장성입니다. 예를 들어 일반 로그인만 필요한 서비스라면 이메일/비밀번호 로그인과 세션 관리만 사용할 수 있고, 보안 요구사항이 커지면 2FA, 패스키, 조직 관리 같은 기능을 플러그인으로 추가할 수 있습니다. Better Auth의 2FA 플러그인은 OTP, TOTP, 백업 코드, 신뢰할 수 있는 기기 관리 등을 지원하고, 패스키 플러그인은 WebAuthn/FIDO2 기반의 비밀번호 없는 로그인을 지원합니다.

 

또 하나의 특징은 타입 안정성입니다. TypeScript 프로젝트에서 인증 관련 API, 세션, 사용자 정보 등을 타입 기반으로 다룰 수 있도록 설계되어 있습니다. 그래서 인증 로직이 복잡해질수록 “어떤 데이터가 오고 가는지”를 코드 레벨에서 확인하기 좋습니다.

 

Next.js 프로젝트에서는 Better Auth를 사용해 서버 쪽 인증 설정을 만들고, 클라이언트에서는 로그인, 로그아웃, 세션 조회 같은 기능을 호출하는 구조로 사용할 수 있습니다. 인증 정보를 쿠키 기반 세션으로 관리하면 Server Component, Route Handler, Server Action에서도 현재 로그인 사용자를 확인하기 좋습니다.

Auth.js

Auth.js는 예전 이름으로 NextAuth.js라고 많이 알려진 인증 라이브러리입니다. Next.js에서 소셜 로그인이나 세션 관리를 구현할 때 오래 사용되어 온 선택지입니다. 현재 Auth.js 문서에서는 표준 Web API 기반의 런타임 독립 인증 라이브러리이며, Next.js, SvelteKit, Express, Qwik 등 여러 프레임워크와 통합할 수 있다고 설명합니다.

 

Next.js에서 사용할 때는 여전히 next-auth 패키지를 사용하며, v5부터는 auth.ts를 중심으로 설정하는 구조가 많이 사용됩니다. auth() 함수를 통해 Server Component, Route Handler, Proxy/Middleware 등에서 세션을 확인할 수 있습니다. Auth.js의 Next.js 문서에서는 Route Handler를 통해 OAuth, Email Provider, /api/auth/session 같은 인증 엔드포인트를 노출하는 구조를 설명합니다.

 

Auth.js의 가장 큰 장점은 소셜 로그인 Provider 생태계입니다. Google, GitHub, Discord, Apple 같은 OAuth Provider를 비교적 쉽게 붙일 수 있습니다. “빠르게 소셜 로그인을 붙이고, 세션을 관리하고, 보호된 페이지를 만들고 싶다”는 목적이라면 Auth.js가 여전히 좋은 선택지입니다.

 

또한 레퍼런스가 많습니다. NextAuth.js라는 이름으로 오랫동안 사용되어 왔기 때문에 블로그 글, 예제 코드, 오류 해결 사례가 많이 쌓여 있습니다. 팀원이 NextAuth 경험이 있다면 도입 장벽도 낮은 편입니다.

 

다만 Auth.js v5는 기존 NextAuth v4와 구조가 일부 달라졌습니다. 공식 마이그레이션 문서에서도 v5를 next-auth 패키지의 주요 재작성 버전으로 설명합니다. 따라서 기존 v4 자료를 그대로 따라 하면 맞지 않는 부분이 있을 수 있습니다.

 

둘의 차이를 간단히 보자면

구분  Better Auth Auth.js
성격 TypeScript 중심 인증·인가 프레임워크 NextAuth 계열 인증 라이브러리
강점 타입 안정성, 플러그인 확장, 2FA/패스키/조직 기능 소셜 로그인 Provider, Next.js 레퍼런스, 익숙한 생태계
사용감 인증 시스템을 직접 구성하는 느낌 OAuth 로그인과 세션 관리를 빠르게 붙이는 느낌
적합한 경우 인증 요구사항이 복잡하거나 확장 가능성이 큰 서비스 소셜 로그인 중심의 일반적인 Next.js 서비스
주의점 상대적으로 학습할 개념이 있음 v4/v5 차이를 확인해야 함

 

정리하면, Auth.js는 Next.js에서 검증된 소셜 로그인/세션 관리 도구에 가깝고, Better Auth는 타입 안정성과 플러그인 확장성을 중심으로 인증 기능을 더 세밀하게 구성하는 도구에 가깝습니다.

 

개인 프로젝트나 블로그, 일반적인 서비스에서 Google/GitHub 로그인 정도가 필요하다면 Auth.js가 접근하기 쉽습니다. 반대로 회원가입, 이메일 인증, 2FA, 패스키, 조직/권한 관리처럼 인증 요구사항이 점점 커질 가능성이 있다면 Better Auth를 검토해볼 만합니다.

proxy.ts에서 인증 기반 접근 제어 구현

Next.js 16부터는 기존 middleware.ts라는 이름이 proxy.ts로 변경되었습니다. 기능 자체는 요청이 완료되기 전에 서버에서 코드를 실행하고, 요청을 리다이렉트하거나 rewrite하거나 헤더를 수정할 수 있다는 점에서 기존 Middleware와 같은 역할을 합니다.

공식 문서에서도 Next.js 16부터 Middleware가 Proxy로 이름이 변경되었고, 기능은 동일하다고 설명합니다.

 

proxy.ts는 인증 기반 접근 제어를 구현할 때 유용합니다. 예를 들어 로그인하지 않은 사용자가 /dashboard, /mypage, /admin 같은 보호된 경로에 접근하면 로그인 페이지로 이동시키고, 이미 로그인한 사용자가 /login에 접근하면 메인 페이지로 이동시키는 흐름을 만들 수 있습니다.

 

예시는 다음과 같습니다.

// src/proxy.ts
import {NextRequest,NextResponse }from'next/server';

constprotectedRoutes= ['/dashboard','/mypage','/admin'];
constauthRoutes= ['/login','/signup'];

exportfunctionproxy(request:NextRequest) {
const { pathname }=request.nextUrl;

constsessionToken=request.cookies.get('session')?.value;

constisLoggedIn=Boolean(sessionToken);
constisProtectedRoute=protectedRoutes.some((route) =>
pathname.startsWith(route)
  );
constisAuthRoute=authRoutes.some((route) =>
pathname.startsWith(route)
  );

if (!isLoggedIn&&isProtectedRoute) {
constloginUrl=newURL('/login',request.url);
loginUrl.searchParams.set('redirect',pathname);

returnNextResponse.redirect(loginUrl);
  }

if (isLoggedIn&&isAuthRoute) {
returnNextResponse.redirect(newURL('/',request.url));
  }

returnNextResponse.next();
}

exportconstconfig= {
  matcher: [
'/dashboard/:path*',
'/mypage/:path*',
'/admin/:path*',
'/login',
'/signup',
  ],
};

이 코드는 요청이 실제 페이지에 도달하기 전에 쿠키에 세션이 있는지 확인합니다. 세션이 없는데 보호된 페이지에 접근하려고 하면 /login으로 보냅니다. 반대로 이미 로그인한 사용자가 로그인 페이지에 접근하면 홈으로 이동시킵니다.

 

다만 proxy.ts만으로 모든 보안 처리가 끝난다고 보면 안 됩니다. Proxy는 페이지 접근을 빠르게 제어하는 데 유용하지만, 실제 데이터 접근 권한은 Server Component, Route Handler, Server Action, 백엔드 API에서도 다시 확인해야 합니다. 사용자가 UI 경로 접근을 막았다고 해서 서버 액션이나 API 요청까지 자동으로 보호되는 것은 아니기 때문입니다.

 

따라서 실무에서는 보통 다음과 같이 나누어 처리합니다. proxy.ts에서는 페이지 접근을 1차로 제어하고, Server Component에서는 현재 사용자 정보를 읽어 화면을 분기하며, Route Handler나 Server Action에서는 실제 데이터 변경 전에 세션과 권한을 다시 검증합니다. 관리자 페이지라면 단순히 로그인 여부만 보는 것이 아니라 사용자의 role까지 확인해야 합니다.

 

예를 들어 관리자 페이지는 다음처럼 role 기반으로 한 번 더 막을 수 있습니다.

// 개념 예시
if (pathname.startsWith('/admin')) {
constrole=request.cookies.get('role')?.value;

if (role!=='admin') {
returnNextResponse.redirect(newURL('/forbidden',request.url));
  }
}

다만 실제 서비스에서는 role 값을 그대로 클라이언트가 조작 가능한 쿠키에 저장하는 방식은 피하는 것이 좋습니다.

role은 세션 토큰을 통해 서버에서 검증하거나, 서명된 토큰 또는 세션 저장소를 통해 확인하는 방식이 더 안전합니다.

정리

Next.js에서 인증은 서버와 클라이언트 경계를 함께 고려해야 하기 때문에 일반적인 React SPA보다 설계할 요소가 많습니다.

특히 Server Components, Route Handlers, Server Actions, Proxy처럼 서버에서 실행되는 지점이 많기 때문에, 인증 정보를 브라우저 저장소에만 두는 방식은 한계가 있습니다.

 

쿠키 기반 인증은 요청과 함께 서버로 자연스럽게 전달되기 때문에 Next.js 구조와 잘 맞습니다. httpOnly, Secure, SameSite 설정을 적절히 사용하면 XSS와 CSRF 위험을 줄이는 데 도움이 됩니다. 반면 JWT 기반 인증은 API 중심 구조나 모바일 앱 연동에서는 편리할 수 있지만, 토큰 저장 위치에 따라 보안 특성이 크게 달라집니다.

 

라이브러리 선택에서는 Better Auth와 Auth.js v5를 함께 비교해볼 수 있습니다. Better Auth는 타입 세이프한 구조와 플러그인 기반 확장성이 강점이고, Auth.js v5는 Next.js 생태계에서 이어져 온 Provider 중심 인증 경험과 레퍼런스가 강점입니다.

 

마지막으로 proxy.ts는 인증 기반 접근 제어의 첫 관문으로 사용할 수 있습니다. 하지만 실제 보안은 Proxy 하나에만 맡기지 않고, 서버 컴포넌트, 서버 액션, API 계층에서도 세션과 권한을 반복적으로 확인하는 구조로 설계하는 것이 안정적입니다.

'Next.js' 카테고리의 다른 글

개인 포트폴리오 페이지를 구현해보자!  (0) 2026.05.24
Next.js 스타일링 전략: Tailwind CSS, shadcn/ui, 그리고 CSS-in-JS  (0) 2026.05.17
Next.js 데이터 페칭과 Server Actions  (2) 2026.04.09
렌더링 전략 완전 이해 - SSG, ISR, PPR, Cache Components  (0) 2026.03.29
Next.js App Router 라우팅 & Proxy 완벽 이해하기  (0) 2026.03.17
'Next.js' 카테고리의 다른 글
  • 개인 포트폴리오 페이지를 구현해보자!
  • Next.js 스타일링 전략: Tailwind CSS, shadcn/ui, 그리고 CSS-in-JS
  • Next.js 데이터 페칭과 Server Actions
  • 렌더링 전략 완전 이해 - SSG, ISR, PPR, Cache Components
수달군
수달군
  • 수달군
    수달 코딩 공장
    수달군
  • 전체
    오늘
    어제
    • 분류 전체보기 (21)
      • React (10)
      • Next.js (7)
      • TypeScript 딥 다이브! (1)
      • 웹 기초 이론 (0)
      • 코딩 테스트 준비 (1)
        • Python 기본 (1)
      • AI 도구들 (0)
      • 프로젝트 회고 (0)
      • 자료구조 (0)
      • 일상 (0)
      • 해외 여행 (0)
      • 국내 여행 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 태그

    python
    입력값
    입력
    파이썬 초보
    it
    코딩
    input
    파이썬
    coding
    입력받기
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
수달군
Next.js에서의 인증 전략과 쿠키 vs 토큰
상단으로

티스토리툴바