프로그래밍 언어/NODE JS

자주 사용하는 미들웨어

· 코딩마이데이

미들웨어는 익스프레스의 핵심입니다. 요청과 응답의 중간(middle)에 위치하여 미들웨어라고 부릅니다. 라우터와 에러 핸들러 또한 미들웨어의 일종으므로 미들웨어가 익스프레스의 전부라고 해도 과언이 아닙니다. 미들웨어 요청과 응담을 조작하여 기능을 추가하기도 하고, 나쁜 요청을 걸러내기도 합니다.

미들웨어는 app.use와 함께 사용됩니다. app.use(미들웨어) 꼴입니다. 익스프레스 서버에 미들웨어를 연결해봅시다.

app.js

const express = require("express");
const path = require("path");

const app = express();
app.set("port", process.env.PORT || 3000);

app.use((req, res, next) => {
  console.log("모든 요청에 다 실행됩니다.");
  next();
});
app.get(
  "/",
  (req, res, next) => {
    console.log("GET / 요청에서만 실행됩니다.");
    next();
  },
  (req, res) => {
    throw new Error("에러는 에러 처리 미들웨어로 갑니다.");
  }
);

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).send(err.message);
});

app.listen(app.get("port"), () => {
  console.log(app.get("port"), "번 포트에서 대기 중");
});

 

app.use에 매개변수가 req, res, next인 함수를 넣으면 됩니다. 미들웨어는 위에서부터 아래로 순서대로 실행되면서 요청과 응답 사이에 특별한 기능을 추가할 수 있습니다. 이번에는 next라는 세 번째 매개변수를 사용하는데, 다음 미들웨어로 넘어가는 함수입니다. next를 실행하지 않으면 다음 미들웨어가 실행되지 않습니다.

주소를 첫 번쩨 인수로 넣어주지 않는다면 미들웨어는 모든 요청에서 실행되고, 주소를 넣는다면 해당하는 요청에서만 실행된다고 보면 됩니다.

 

app.use(미들웨어) 모든 요청에서 미들웨어 실행
app.use('/abc', 미들웨어) abc로 시작하는 요청에서 미들웨어 실행
app.post('/abc', 미들웨어) abc로 시작하는 POST 요청에서 미들웨어 실행

 

app.use나 app.get 같은 라우터에 미들웨어를 여러 개 정착할 수 있습니다. 현재 app.get 라우터에 미들웨어가 두 개 연결되어 있습니다. 다만 이때도 next를 호출해야 다음 미들웨어로 넘어갈 수 있습니다.

현재 app.get('/')의 두 번째 미들웨어에서 에러가 발생하고, 이 에러는 그 아래에 있는 에러 처리 미들웨어에 전달됩니다.

에러 처리 미들웨어는 매개변수가 err, req, res, next로 네 개입니다. 모든 매개변수를 사용하지 않더라도 매개변수가 반드시 네 개여야 합니다. 첫 번째 매개변수 err에는 에러에 관한 정보가 담겨 있습니다. res.status 메서드로 HTTP 상태 코드를 지정할 수 있습니다. 에러 처리 미들웨어를 직접 연결하지 않아도 기본적으로 익스프레스가 에러를 처리하긴 합니다. 에러 처리 미들웨어는 특별한 경우가 아니면 가장 아래에 위치하도록 합니다.

 

localhost:3000에 접속하면 다음과 같이 콘솔에 출력합니다.

콘솔

모든 요청에 다 실행됩니다.
GET / 요청에서만 실행됩니다.
Error: 에러는 에러 처리 미들웨어로 갑니다.
...

 

localhost:3000 접속 화면

 

미들웨어를 통해 요청과 응답에 다양한 기능을 추가할 수 있고, 이미 많은 사람이 유용한 기능들을 패키지로 만들어두었습니다.

콘솔

$ npm i morgan cookie-parser express-session dotenv

 

dotenv를 제외한 다른 패키지는 미들웨어입니다. dotenv는 process.env를 관리하기 위해 설치했습니다.

 

app.js

const express = require("express");
const mogan = require("morgan");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const dotenv = require("dotenv");
const path = require("path");

dotenv.config();
const app = express();
app.set("port", process.env.PORT || 3000);

app.use(mogan("dev"));
app.use("/", express.static(path.join(__dirname, "public")));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
  session({
    resave: false,
    saveUninitialized: false,
    secret: process.env.COOKIE_SECRET,
    cookie: {
      httpOnly: true,
      secure: false,
    },
    name: "session-cookie",
  })
);

app.use((req, res, next) => {
  console.log("모든 요청에 다 실행됩니다.");
  next();
});
app.get(
  "/",
  (req, res, next) => {
    console.log("GET / 요청에서만 실행됩니다.");
    next();
  },
  (req, res) => {
    throw new Error("에러는 에러 처리 미들웨어로 갑니다.");
  }
);

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).send(err.message);
});

app.listen(app.get("port"), () => {
  console.log(app.get("port"), "번 포트에서 대기 중");
});

 

.env

COOKIE_SECRET=cookiesecret

 

설치했던 패키지들을 불러온 뒤 app.use에 연결합니다. req, res, next 같은 것들이 보이지 않아 당황스러울 수도 있는데, 미들웨어 내부에 들어 있습니다. next도 내부적으로 호출하기에 다음 미들웨어로 넘어갈 수 있습니다.

dotenv 패키지는 .env 파일을 열어서 process.env로 만듭니다. dotenv 패키지는 이름이 dot(점)+env인 이유입니다. 키=값 형식으로 추가하면 됩니다. process.env를 별도의 파일로 관리하는 이유는 보안과 설정의 편의성 때문입니다. 비밀 키들을 소스 코드에 그대로 적어두면 소스 코드가 유출되었을 때 키도 같이 유출됩니다. 따라서 .env 같은 별도의 파일에 비밀 키를 적어두고 dotenv 패키지로 비밀 키를 로딩하는 방식으로 관리하곤 합니다. 소스 코드가 유출되더라도 .env 파일만 잘 관리하면 비밀 키는 지킬 수 있습니다.

'프로그래밍 언어 > NODE JS' 카테고리의 다른 글

static  (0) 2025.06.16
morgan  (0) 2025.06.16
익스프레스 프로젝트 시작하기  (0) 2025.06.10
패키지 배포하기  (0) 2025.06.07
기타 npm 명령어  (2) 2025.06.07