19.Nest.js와 Next.js에서 Middleware와 Guard 사용하기, Nest.js에서 미들웨어와 가드로 인증 및 권한 제어하기

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을 사용하여 권한 제어를 할 수 있습니다.

Note: 각 프레임워크의 생태계와 기능은 지속적으로 발전하고 있으므로, 항상 최신 문서를 참조하여 구현하는 것이 좋습니다.

더 많은 정보와 예제는 공식 문서를 참고하시기 바랍니다.