Next.js 16 인증: 3계층 보안 모델로 허점 차단

by DD
1시간 전
조회수 0

Next.js 16에서 `middleware.ts`가 `proxy.ts`로 변경되며 Node.js 런타임 지원으로 JWT 검증 라이브러리 활용성이 향상됨

`proxy.ts`는 URL 패턴 기반의 빠른 라우트 보호에 유용하나, 데이터 소유권 같은 세부 권한 검증에는 한계가 있음

Server Components는 프록시 이후 실행되는 두 번째 검증 계층으로, DB 의존적인 권한 검사를 수행함

데이터 레이어 자체에 `userId` 기반의 접근 제어를 내장하여 모든 데이터 요청 시 최종적인 보안 검증을 수행함

프록시, Server Component, 데이터 레이어의 3계층 보안 모델 구축이 필수적임을 강조함

Next.js 16 `proxy.ts`의 역할과 한계

Next.js 16에서 도입된 `proxy.ts`는 기존 `middleware.ts`를 대체하며 Node.js 런타임을 기본 지원하여 JWT 검증 라이브러리 활용성을 크게 높였습니다. 이는 Edge 런타임의 암호화 제약을 해소하여 인증 관련 작업에 유리합니다. 하지만 `proxy.ts`는 URL 패턴 매칭에 기반한 빠른 네트워크 경계 검증(Fast Network Boundary Validation)에 특화되어 있으며, 요청된 특정 데이터(예: 송장 ID)의 소유권이나 접근 권한 같은 세밀한 데이터 레벨 권한 검증(Fine-grained Data-Level Authorization)은 수행할 수 없습니다. 이는 `proxy.ts`가 데이터베이스에 접근할 수 없기 때문이며, 보안 계층으로서의 역할에 근본적인 한계가 있음을 시사합니다.

Server Components를 활용한 두 번째 인증 계층

Server Components는 `proxy.ts` 이후에 렌더링되므로, 프록시에서 놓칠 수 있는 보안 허점을 보완하는 두 번째 방어선 역할을 수행합니다. 특히, 데이터베이스 조회(Database Lookups)가 필요한 사용자별 권한(Permissions) 검증을 이 계층에서 처리하는 것이 중요합니다. 예를 들어, 특정 사용자가 특정 송장에 접근할 권한이 있는지 여부는 DB 조회를 통해서만 확인할 수 있습니다. `proxy.ts`에서 JWT에 포함된 역할(Role) 정보만으로는 이러한 세부 권한을 검증할 수 없으므로, Server Component에서 `userId`를 이용해 DB에서 권한을 확인하는 로직이 필수적입니다. 이는 역할(Role)과 권한(Permission)의 분리를 통해 관리 효율성을 높이는 전략입니다.

데이터 레이어에서의 최종 접근 제어

가장 강력한 보안 계층은 실제 데이터를 반환하는 데이터 접근 함수 내부에 구현됩니다. 모든 데이터 조회 함수는 `userId`를 인자로 받아, SQL 쿼리 자체에 사용자 ID를 포함시켜 데이터 접근을 제어해야 합니다. 예를 들어, `SELECT * FROM invoices WHERE id = $1 AND user_id = $2`와 같이 쿼리하면, 해당 사용자가 소유한 데이터만 조회할 수 있습니다. 이 방식은 SQL Injection 방지와 함께 데이터 소유권 검증(Data Ownership Verification)을 확실하게 보장하며, 라우트나 프록시 설정 오류와 관계없이 항상 작동합니다. 'Not found'와 'Not authorized' 오류를 통합하여 정보 누출(Information Leakage) 가능성을 차단하는 것도 중요한 보안 패턴입니다.

Next.js 16 인증 시스템의 3계층 모델

안전한 Next.js 인증 시스템은 프록시(Proxy), Server Component, 데이터 레이어(Data Layer)의 세 가지 독립적인 검증 계층으로 구성되어야 합니다. 프록시는 빠른 라우트 접근 제어를, Server Component는 DB 기반의 페이지 렌더링 권한을, 데이터 레이어는 개별 레코드 접근을 최종적으로 제어합니다. 이 중 하나라도 누락되면 보안 허점이 발생할 수 있으며, 특히 데이터 레이어의 접근 제어 누락은 흔히 간과되는 문제입니다. 또한, 인증 토큰은 쿠키(Cookie)에 저장되어야 프록시가 접근 가능하며, `localStorage`는 보안상 부적합합니다. 이 3계층 모델은 단일 실패 지점(Single Point of Failure)을 제거하여 시스템의 복원력과 보안성을 크게 향상시킵니다.

Next.js 16 `proxy.ts` 마이그레이션 및 런타임 변경

Next.js 16에서는 `middleware.ts`가 `proxy.ts`로 변경되었으며, 이는 Node.js 런타임 지원을 기본으로 합니다. 이 변경은 Edge 런타임의 제한적인 암호화 기능 문제를 해결하여 `jose`와 같은 표준 JWT 라이브러리를 제약 없이 사용할 수 있게 합니다. 마이그레이션은 `@next/codemod` CLI 도구를 통해 자동화할 수 있습니다. `proxy.ts`는 리다이렉트, 헤더 수정 등 네트워크 경계에서의 빠른 작업에 최적화되어 있으며, 느린 데이터 페칭이나 복잡한 세션 관리는 이 계층에서 처리하지 않도록 설계되었습니다. `middleware.ts`는 Edge 런타임용으로 계속 지원되지만, 향후 제거될 예정이므로 `proxy.ts`로의 전환이 권장됩니다.

I Thought My Next.js 16 Auth Was Solid. One Afternoon Proved Otherwise.

댓글 0

첫 번째 댓글을 남겨보세요!