Middleware 완벽 마스터
Middleware의 핵심 개념과 실전 활용법
학습 항목
이미지 로딩 중...
Middleware 활용 완벽 가이드
웹 애플리케이션에서 요청/응답 사이클 중간에 실행되는 Middleware의 핵심 개념과 활용법을 학습합니다. Express, Next.js 등에서 인증, 로깅, 에러 처리 등을 효율적으로 구현하는 방법을 다룹니다.
들어가며
이 글에서는 Middleware 활용 완벽 가이드에 대해 상세히 알아보겠습니다. 총 10가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- 기본_Middleware_구조
- 인증_Middleware
- 에러_처리_Middleware
- Next.js_Middleware
- CORS_Middleware
- 요청_본문_파싱_Middleware
- 속도_제한_Middleware
- 조건부_Middleware_실행
- 비동기_Middleware_처리
- Middleware_체인_순서
1. 기본_Middleware_구조
개요
Middleware는 요청(req), 응답(res), 다음 함수(next)를 매개변수로 받는 함수입니다. next()를 호출하여 다음 Middleware로 제어를 전달합니다.
코드 예제
const loggerMiddleware = (req, res, next) => {
console.log(`${req.method} ${req.url}`);
console.log('Time:', new Date().toISOString());
next(); // 다음 미들웨어로 이동
};
app.use(loggerMiddleware);
설명
모든 요청에 대해 HTTP 메서드와 URL을 로깅한 후, next()로 다음 처리 단계로 넘어갑니다.
2. 인증_Middleware
개요
사용자 인증 상태를 확인하고, 인증되지 않은 요청을 차단하는 Middleware입니다. JWT 토큰 검증 등에 활용됩니다.
코드 예제
const authMiddleware = (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
// 토큰 검증 로직
req.user = verifyToken(token);
next();
};
설명
Authorization 헤더를 확인하여 토큰이 없으면 401 에러를 반환하고, 있으면 검증 후 다음 단계로 진행합니다.
3. 에러_처리_Middleware
개요
애플리케이션에서 발생하는 에러를 중앙에서 처리하는 Middleware입니다. 4개의 매개변수(err, req, res, next)를 받는 특별한 형태입니다.
코드 예제
const errorHandler = (err, req, res, next) => {
console.error(err.stack);
res.status(err.status || 500).json({
error: err.message,
...(process.env.NODE_ENV === 'dev' && { stack: err.stack })
});
};
app.use(errorHandler);
설명
에러 객체를 받아 상태 코드와 메시지를 클라이언트에 전달하며, 개발 환경에서는 스택 트레이스도 포함합니다.
4. Next.js_Middleware
개요
Next.js 13+에서는 middleware.ts 파일로 라우팅 전에 실행되는 Middleware를 정의합니다. 페이지 접근 전 인증, 리다이렉트 등을 처리합니다.
코드 예제
import { NextResponse } from 'next/server';
export function middleware(request) {
const token = request.cookies.get('token');
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
설명
대시보드 경로 접근 시 토큰 쿠키를 확인하고, 없으면 로그인 페이지로 리다이렉트합니다.
5. CORS_Middleware
개요
Cross-Origin Resource Sharing을 설정하여 다른 도메인에서의 API 요청을 허용하는 Middleware입니다.
코드 예제
const corsMiddleware = (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') return res.sendStatus(200);
next();
};
설명
응답 헤더에 CORS 설정을 추가하여 모든 도메인에서의 요청을 허용하고, OPTIONS 요청은 즉시 응답합니다.
6. 요청_본문_파싱_Middleware
개요
클라이언트가 보낸 JSON이나 URL-encoded 데이터를 파싱하여 req.body로 접근 가능하게 만듭니다.
코드 예제
const express = require('express');
const app = express();
app.use(express.json()); // JSON 파싱
app.use(express.urlencoded({ extended: true })); // URL-encoded 파싱
app.post('/api/users', (req, res) => {
console.log(req.body); // 파싱된 데이터 접근
res.json({ received: req.body });
});
설명
express.json()과 express.urlencoded()로 요청 본문을 자동 파싱하여 req.body 객체로 사용할 수 있습니다.
7. 속도_제한_Middleware
개요
특정 시간 내 요청 횟수를 제한하여 API 남용과 DDoS 공격을 방지하는 Middleware입니다.
코드 예제
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15분
max: 100, // 최대 100개 요청
message: 'Too many requests, please try again later.'
});
app.use('/api/', limiter);
설명
15분 동안 최대 100개의 요청만 허용하고, 초과 시 에러 메시지를 반환하여 서버를 보호합니다.
8. 조건부_Middleware_실행
개요
특정 경로나 조건에서만 Middleware를 실행하도록 설정할 수 있습니다. 효율적인 리소스 사용이 가능합니다.
코드 예제
const adminOnly = (req, res, next) => {
if (req.user?.role !== 'admin') {
return res.status(403).json({ error: 'Admin only' });
}
next();
};
// 특정 라우트에만 적용
app.delete('/api/users/:id', authMiddleware, adminOnly, deleteUser);
설명
관리자 권한이 있는 사용자만 특정 라우트에 접근할 수 있도록 Middleware를 체인으로 연결합니다.
9. 비동기_Middleware_처리
개요
비동기 작업(DB 조회, 외부 API 호출 등)을 수행하는 Middleware는 async/await을 사용하고 에러를 적절히 처리해야 합니다.
코드 예제
const asyncHandler = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
const checkUserExists = asyncHandler(async (req, res, next) => {
const user = await User.findById(req.params.id);
if (!user) return res.status(404).json({ error: 'User not found' });
req.user = user;
next();
});
설명
asyncHandler 래퍼로 비동기 함수를 감싸면 에러가 자동으로 에러 핸들러로 전달되어 try-catch 없이 사용할 수 있습니다.
10. Middleware_체인_순서
개요
Middleware는 등록된 순서대로 실행되므로, 순서가 매우 중요합니다. 로깅 → 파싱 → 인증 → 라우트 → 에러 처리 순서를 권장합니다.
코드 예제
app.use(loggerMiddleware); // 1. 로깅
app.use(express.json()); // 2. 본문 파싱
app.use(corsMiddleware); // 3. CORS 설정
app.use('/api', authMiddleware); // 4. 인증 (특정 경로)
app.use('/api/users', userRoutes);// 5. 라우트
app.use(errorHandler); // 6. 에러 처리 (항상 마지막)
설명
Middleware 순서가 잘못되면 예상치 못한 동작이 발생할 수 있으므로, 논리적 흐름에 맞게 배치해야 합니다.
마치며
이번 글에서는 Middleware 활용 완벽 가이드에 대해 알아보았습니다. 총 10가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#JavaScript #Middleware #Express #NextJS #Backend