Nest.js와 Next.js는 현대의 웹 애플리케이션 개발에 있어 강력한 프레임워크입니다. 이 두 프레임워크는 쉽게 스케일링 가능한 애플리케이션 아키텍처를 제공합니다. 본 강좌에서는 Nest.js와 Next.js에서 각각 Middleware와 Guard를 사용하여 인증 및 권한 제어를 구현하는 방법에 대해 자세히 설명하겠습니다.
1. Middleware란?
Middleware는 두 개의 함수 간에 실행되는 코드로, 주로 요청(Request)과 응답(Response) 객체에 대한 처리를 수행하는 데 사용됩니다. 예를 들어, 요청을 로깅하거나 요청을 수정하거나 사용자를 인증하는 데 사용할 수 있습니다. Nest.js에서는 미들웨어를 사용하여 요청을 가로채고 어떤 작업을 수행할 수 있습니다.
Middleware의 특징
- 요청을 가로챌 수 있다.
- 응답을 수정할 수 있다.
- 비즈니스 로직과 데이터베이스 접근을 할 수 있다.
2. Nest.js에서 Middleware 구현하기
Nest.js에서는 미들웨어를 만들기 위해 기본적으로 MiddlewareConsumer
를 사용합니다. 미들웨어는 클래스 기반으로 만들 수 있으며, @Injectable()
데코레이터를 사용하여 의존성을 주입받을 수 있습니다.
예제: 인증 미들웨어 구현하기
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class AuthMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
const token = req.headers['authorization'];
if (token) {
// 토큰 검증 로직
next();
} else {
res.status(403).send('Forbidden');
}
}
}
위 코드에서 AuthMiddleware
는 사용자의 요청에서 Authorization 헤더를 확인하고, 토큰이 유효한지 검사합니다. 유효한 경우 next()
를 호출하여 다음 미들웨어로 진행하고, 그렇지 않으면 403 Forbidden 에러를 반환합니다.
Middleware 등록하기
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { AuthMiddleware } from './auth.middleware';
@Module({
// 모듈 설정
})
export class AppModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(AuthMiddleware)
.forRoutes('*'); // 모든 라우트에 적용
}
}
3. Guard란?
Guard는 요청이 라우터 핸들러에 도달하기 전에 특정 조건을 평가하여 요청을 차단할 수 있는 메커니즘입니다. 예를 들어, 사용자가 특정 사용자 역할이나 권한을 가지고 있는지 검증할 수 있습니다.
Guard의 특징
- 요청 처리 여부를 결정할 수 있다.
- 특정 조건에 따라 요청을 허용하거나 거부한다.
4. Nest.js에서 Guard 구현하기
Guard는 CanActivate
인터페이스를 구현하여 생성할 수 있습니다. 주로 사용자의 권한을 체크하거나 인증 여부를 확인하는 데 활용됩니다.
예제: Role Guard 구현하기
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
@Injectable()
export class RoleGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
const user = request.user;
// 사용자 역할 확인 로직
return user && user.role === 'admin';
}
}
Guard 등록하기
import { Controller, Get, UseGuards } from '@nestjs/common';
import { RoleGuard } from './role.guard';
@Controller('admin')
export class AdminController {
@Get()
@UseGuards(RoleGuard)
getAdminData() {
return 'Admin data!';
}
}
5. Next.js에서 Middleware 사용하기
Next.js는 전통적인 라우터 방식을 샌드위치처럼 레이어링한 형태의 아키텍처를 가지고 있습니다. Middleware는 요청이 특정 API 라우팅 경로에 도달하기 전에 사용되는 함수로, 인증, 권한 등 다양한 로직을 처리하는 데 사용될 수 있습니다.
예제: Next.js에서 미들웨어 구현하기
import { NextResponse } from 'next/server';
export function middleware(req) {
const token = req.headers.get('authorization');
if (token) {
// 토큰 검증 로직
return NextResponse.next();
} else {
return NextResponse.redirect('/login');
}
}
Middleware 등록하기
Next.js에서는 Middleware를 전체 애플리케이션이나 특정 경로에 적용할 수 있습니다. middleware.ts
파일을 루트에 생성하고, 그 내부에 미들웨어 로직을 정의하면 됩니다.
6. Next.js에서 Guard 사용하기
Next.js에서는 Guard를 명시적으로 구현하는 것이 아니라, 내부 컴포넌트에서 조건부 렌더링을 통해 인증 및 권한 제어를 수행할 수 있습니다. 예를 들어, API 요청을 통해 사용자 정보를 가져오고, 이를 기반으로 컴포넌트를 조건부로 렌더링할 수 있습니다.
예제: Hook을 사용한 Role Guard 구현하기
import { useEffect, useState } from 'react';
function useAuth(requiredRole) {
const [user, setUser] = useState(null);
useEffect(() => {
const getUserData = async () => {
const res = await fetch('/api/user');
const data = await res.json();
setUser(data);
};
getUserData();
}, []);
return user && user.role === requiredRole;
}
// 사용 예시
function AdminPage() {
const isAdmin = useAuth('admin');
if (!isAdmin) {
return Access Denied
;
}
return Admin Page
;
}
7. 결론
Nest.js와 Next.js 모두에서 Middleware와 Guard를 활용하면 애플리케이션의 인증 및 권한 제어를 효율적으로 관리할 수 있습니다. Nest.js에서는 미들웨어와 가드를 클래스로 정의하고 사용할 수 있으며, Next.js에서는 미들웨어를 통해 요청 처리를 우선적으로 수행하고, 조건부 렌더링이나 Hook을 사용하여 권한 제어를 할 수 있습니다.
더 많은 정보와 예제는 공식 문서를 참고하시기 바랍니다.