Post

NextJS 인증 아키텍처

NextJS 인증 흐름과 세션/서버·클라이언트 가드 역할, 흔한 실수와 체크리스트

NextJS 인증 아키텍처

“로그인 기능”이 아니라 “요청 신뢰 흐름”으로 이해하자

NextJS 인증을 여러 번 설계하면서 반복해서 확인한 사실이 있다.

인증 문제의 대부분은
라이브러리 선택이 아니라 흐름 이해 부족에서 발생한다.

이 글은 next-auth, Lucia 같은 도구 설명을 하지 않는다.
대신 NextJS에서 인증이 어떻게 흘러가며, 어디서 통제되어야 하는지를 단계별로 정리한다.


1단계. 인증의 전체 흐름

“누가 누구를 언제 신뢰하는가”

NextJS 인증의 핵심 흐름은 다음 6단계로 정리된다.

  1. 사용자가 자격 증명을 제출한다
  2. 서버가 자격 증명을 검증한다
  3. 서버가 신뢰의 증표(세션)를 생성한다
  4. 증표를 클라이언트에 전달한다 (보통 쿠키)
  5. 이후 모든 요청에서 증표를 검증한다
  6. 검증 결과에 따라 접근을 허용하거나 차단한다

중요한 점은 이것이다.

인증은 “로그인 요청”에서 끝나지 않고
모든 요청에서 반복적으로 평가된다


2단계. 서버와 클라이언트의 역할 분리

“인증은 서버 책임, UX는 클라이언트 책임”

❌ 흔한 오해

  • “클라이언트에서 로그인 상태를 관리한다”
  • “로그인 여부는 상태 값이다”

이 접근은 보안적으로 취약하다.


✅ 올바른 역할 분리

서버의 책임

  • 자격 증명 검증
  • 세션 생성 및 검증
  • 보호된 리소스 접근 제어

클라이언트의 책임

  • 로그인 UI 제공
  • 로딩/에러 상태 표현
  • 사용자 경험 관리

👉 신뢰 판단은 항상 서버에서 이뤄져야 한다.


3단계. 세션(Session)의 개념 정리

“로그인 상태”가 아니라 “서버의 약속”

세션을 이렇게 이해하면 대부분의 문제가 사라진다.

세션은
“이 요청이 누구의 요청인지 서버가 기억하기 위한 수단”이다.

핵심 속성

  • 서버가 발급
  • 서버가 검증
  • 클라이언트는 보관만 함

일반적인 구조:

  • 세션 ID 또는 토큰
  • HTTP-only 쿠키에 저장
  • 요청마다 자동 전송

👉 클라이언트는
세션을 해석하지 않는다.


4단계. 서버 가드(Server Guard)의 역할

“접근 가능 여부를 결정하는 마지막 관문”

서버 가드는 다음 위치에서 동작한다.

  • 서버 컴포넌트
  • 서버 액션
  • API Route
  • Middleware

역할은 단순하다.

“이 요청은 신뢰할 수 있는가?”

서버 가드가 해야 할 일

  1. 요청에 포함된 세션 확인
  2. 세션 유효성 검증
  3. 사용자 정보 로드
  4. 접근 허용 / 차단 결정

이 판단은 UI 이전 단계에서 끝나야 한다.


5단계. 클라이언트 가드(Client Guard)의 역할

“보안”이 아니라 “경험”을 위한 장치

클라이언트 가드는 보안을 담당하지 않는다.

역할:

  • 로그인 안 된 사용자에게 리다이렉트
  • 로딩 중 상태 처리
  • 깜빡임(Flicker) 방지

중요한 경계:

클라이언트 가드가 있어도
서버 가드가 없으면 인증은 실패한 설계다.


6단계. 흔한 실수 패턴 (실무에서 가장 자주 발생)

❌ 실수 1: 로그인 상태를 전역 상태로 관리

  • 새로고침 시 상태 소실
  • 서버와 불일치
  • 보안 취약

❌ 실수 2: 클라이언트 가드만으로 보호

  • 직접 URL 접근 가능
  • API 직접 호출 차단 불가

❌ 실수 3: 세션 데이터를 클라이언트에서 신뢰

  • 토큰 내용 직접 사용
  • 권한 판단을 클라이언트에서 수행

❌ 실수 4: 인증과 인가를 혼동

  • 로그인 = 모든 권한 허용
  • 역할/권한 체크 누락

인증 설계 시 필수 체크리스트

  • 인증 판단은 항상 서버에서 이뤄지는가?
  • 세션은 HTTP-only 쿠키로 관리되는가?
  • 서버 가드가 모든 보호 리소스 앞에 있는가?
  • 클라이언트 가드는 UX 용도로만 사용되는가?
  • 인증(누구인가)과 인가(무엇을 할 수 있는가)를 분리했는가?

결론: NextJS 인증은 “기능”이 아니라 “신뢰 흐름”이다

NextJS에서 인증을 잘 설계했다는 것은

  • 로그인 UI를 잘 만들었다 ❌
  • 라이브러리를 잘 골랐다 ❌

가 아니다.

  • 요청이 어떻게 들어오고
  • 어디서 신뢰를 판단하며
  • 언제 차단되는지

흐름이 명확한 상태를 말한다.

인증은 한 번 구현하고 끝나는 기능이 아니라,
모든 요청마다 반복되는 보안 계약이다.


This post is licensed under CC BY 4.0 by the author.