Skip to Content
Suffering builds character

7. 인가

사용자의 인가를 처리하는 방법은 크게 2가지가 있음

1. 낙관적 검증, Optimistic

사용자가 해당 페이지에 접근할 권한이 있는지를 쿠키에 저장된 세션 데이터에서 확인하는 방식

가벼운 인증 처리에 활용할 때 사용

예를 들면 인증 상태에 따라 UI를 페이지에 보여주거나 숨길 때, 혹은 사용자를 권한이나 역할에 기반하여 다른 페이지로 리다이렉트할 때 등이 있음

2. 비관적 검증, Passimistic

사용자가 해당 페이지에 접근할 권한이 있는지를 DB에 저장된 세션 데이터에서 확인하는 방식

이 방법은 보다 안전하고, 민감한 데이터에 접근하는 처리나 동작을 수행할 때 사용함

예를 들면 주문이나 결제와 같이 사용자에게 비용이 발생할 수 있는 기능이나
비밀번호 변경과 같이 개인정보와 관련된 기능을 수행할 때 등이 있음

💡
Tip

Next.js의 추천 관리 방식

  1. Data Access Layer를 만들어서 인가 로직을 한 곳에서 관리
  2. DTO를 만들어서 필수적으로 필요한 데이터만 반환
  3. 선택적으로 미들웨어를 활용하여 Optimistic 검증을 수행

2. 미들웨어를 활용한 낙관적 검증

미들웨어는 모든 라우트 경로에 대해 렌더링을 수행하기 전에 동작하는 계층으로

리다이렉트 로직과 권한이 없는 유저를 사전 필터링하는 형태로 인증을 처리할 수 있음

성능 이슈를 방지하기 위해 미들웨어를 통한 낙관적 검증에서는 세션 정보를 쿠키에서만 조회하며, DB에서 조회하지는 않는 것이 권장됨

미들웨어 로직

middleware.js
import { NextResponse } from 'next/server' import { decrypt } from '@/app/lib/session' import { cookies } from 'next/headers' // 1. 접근을 제한할 경로와 별도의 권한이 없어도 접근할 수 있는 경로를 구분 const protectedRoutes = ['/dashboard'] const publicRoutes = ['/login', '/signup', '/'] export default async function middleware(req) { // 2. 현재 URL로 요청된 경로가 public인지 protected 라우트인지 확인 const path = req.nextUrl.pathname const isProtectedRoute = protectedRoutes.includes(path) const isPublicRoute = publicRoutes.includes(path) // 3. 쿠키에서 암호화된 세션 정보를 복호화 const cookie = (await cookies()).get('session')?.value const session = await decrypt(cookie) // 5. 아직 로그인을 수행하지 않은 사용자일 경우 로그인 페이지로 리다이렉트 if (isProtectedRoute && !session?.userId) { return NextResponse.redirect(new URL('/login', req.nextUrl)) } // 6. 인증된 사용자의 경우 보호된 경로인 /dashboard로 리다이렉트 if ( isPublicRoute && session?.userId && !req.nextUrl.pathname.startsWith('/dashboard') ) { return NextResponse.redirect(new URL('/dashboard', req.nextUrl)) } return NextResponse.next() } // api, static 경로 등에 대해서는 미들웨어가 동작하지 않도록 적용 export const config = { matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'], }
💡
Tip

미들웨어는 초기 검증에 유용할 수 있지만 데이터 보호를 위한 유일한 방어 수단이 되어서는 안되며,
대부분의 보안 검사는 데이터 소스에 최대한 가깝게 수행하는 것이 권장됨

Last updated on