Node.JS - 요청 흐름 파악하기

변우영·2024년 9월 20일

NodeJS

목록 보기
7/11

<목표>
Node JS 의 코드 흐름을 이해 할 수 있다.

미들웨어와 라우터의 동작 원리 이해하기

1. 미들웨어란 무엇인가?

미들웨어의 기본 개념

미들웨어(Middleware)는 요청(Request)과 응답(Response) 사이에 위치하여 여러 기능을 수행할 수 있는 함수입니다. Express 애플리케이션에서 미들웨어는 다음과 같은 역할을 할 수 있습니다.

  • 요청 처리 전 로깅
  • 인증 및 권한 부여
  • 요청 본문(body) 파싱
  • 특정 라우터로 요청 전달
  • 에러 처리

미들웨어는 다음과 같은 형식을 갖습니다

function middleware(req, res, next) {
  // 미들웨어 로직
  next(); // 다음 미들웨어로 넘어갑니다.
}

next() 함수를 호출해야 다음 미들웨어로 넘어가거나 라우터로 이동하게 됩니다.

2. 인증 미들웨어의 동작 방식

2-1. 인증 미들웨어의 역할

인증 미들웨어는 클라이언트의 요청이 인증된 사용자인지 확인하는 역할을 합니다. 주로 JWT, 세션, API 키 등을 사용하여 인증 여부를 판단합니다.

2-2. 구현 예시

JWT를 이용한 인증 미들웨어를 구현해 보겠습니다.

const jwt = require('jsonwebtoken');

function authMiddleware(req, res, next) {
  const token = req.headers['authorization'];
  
  if (!token) {
    return res.status(401).json({ message: '인증 토큰이 필요합니다.' });
  }

  jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
    if (err) {
      return res.status(403).json({ message: '유효하지 않은 토큰입니다.' });
    }
    
    req.user = decoded; // 인증된 사용자 정보를 요청 객체에 추가합니다.
    next(); // 인증이 완료되었으므로 다음 미들웨어 또는 라우터로 이동합니다.
  });
}

module.exports = authMiddleware;

위 예시에서 authMiddlewareauthorization 헤더에서 JWT를 가져와 이를 검증하고, 검증에 성공하면 요청 객체에 user 정보를 추가합니다. 이후 next()를 호출하여 다음 미들웨어로 이동하게 됩니다.

3. 에러 처리 미들웨어의 동작 방식

3-1. 에러 처리 미들웨어의 역할

에러 처리 미들웨어는 요청 처리 중 발생한 에러를 잡아내고, 이를 적절하게 클라이언트에게 응답하는 역할을 합니다. Express에서는 마지막 미들웨어로 위치시키는 것이 일반적입니다.

3-2. 구현 예시

function errorMiddleware(err, req, res, next) {
  console.error(err.stack); // 에러 스택을 서버 콘솔에 출력합니다.

  res.status(500).json({
    message: '서버에서 오류가 발생했습니다.',
    error: err.message
  });
}

module.exports = errorMiddleware;

에러 처리 미들웨어는 일반 미들웨어와 다르게 네 개의 인자를 받습니다. 첫 번째 인자인 err는 발생한 에러를 의미합니다. 이 미들웨어에서는 에러 스택을 출력하고, 클라이언트에게 500 상태 코드와 에러 메시지를 응답합니다.

4. 라우터의 동작 방식

4-1. 라우터의 역할

라우터(Router)는 클라이언트의 요청 URL에 따라 요청을 처리할 핸들러를 지정하는 역할을 합니다. 예를 들어, /api/users 경로로 들어오는 요청은 사용자 관련 요청으로 처리하고, /api/products 경로로 들어오는 요청은 상품 관련 요청으로 처리합니다.

4-2. 구현 예시

사용자 관련 라우터를 다음과 같이 구현할 수 있습니다.

const express = require('express');
const userController = require('./controllers/userController');
const authMiddleware = require('./middlewares/authMiddleware');

const userRouter = express.Router();

userRouter.post('/login', userController.login);
userRouter.post('/register', userController.register);
userRouter.get('/profile', authMiddleware, userController.getProfile); // 인증이 필요한 경로

module.exports = userRouter;

위 예시에서 userRouterlogin, register 등의 경로를 설정하고, profile 경로는 authMiddleware를 거쳐야만 접근할 수 있게 설정되어 있습니다.

5. 애플리케이션의 전체 동작 과정

5-1. 요청의 흐름

  1. 클라이언트가 서버로 요청을 보냅니다.
  2. 요청이 인증 미들웨어를 거칩니다. 인증이 실패하면 요청은 여기서 종료됩니다.
  3. 인증이 성공하면 라우터로 요청이 전달됩니다.
  4. 라우터에서 해당 요청을 처리하는 컨트롤러 함수가 실행됩니다.
  5. 요청 처리 중 에러가 발생하면 에러 처리 미들웨어로 이동하여 에러를 처리합니다.
  6. 에러가 없다면 응답이 클라이언트에게 전달됩니다.

5-2. 전체 코드 예시

const express = require('express');
const app = express();
const userRouter = require('./routes/userRouter');
const errorMiddleware = require('./middlewares/errorMiddleware');

// JSON 요청 본문을 파싱하는 미들웨어
app.use(express.json());

// 사용자 관련 라우터
app.use('/api/users', userRouter);

// 에러 처리 미들웨어 (항상 마지막에 위치해야 함)
app.use(errorMiddleware);

// 서버 시작
app.listen(3000, () => {
  console.log('서버가 3000번 포트에서 실행 중입니다.');
});
profile
개발자로 한걸음!

0개의 댓글