Express 웹서버 만들기_미들웨어(middleware)

이애옹·2022년 12월 30일
0

Node.js

목록 보기
21/32

📝 미들웨어 이해하기

요청과 응답 중간(middle)에 위치하여 미들웨어라고 부른다. 미들웨어는 요청과 응답을 조작하여 기능을 추가하기도 하고, 나쁜 기능을 걸러내기도 한다.

미들웨어는 주로 app.use와 사용된다.
app.js를 보면 수많은 app.use 메서드가 사용된다는 것을 알수있다.

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

여기서, app.use 메서드의 인자로 들어있는 함수가 미들웨어이다. 미들웨어는 use 메서드app에 장착된다.

제일 위에 있는 logger('dev') 부터 시작하여 미들웨어들을 순차적으로 거친 후, 라우터에서 클라이언트로 응답을 보낸다.


📝 커스텀 미들웨어 만들기

이제 직접 미들웨어를 만들어보자! 요청이 들어올경우 콘솔에 메시지를 찍는 단순 미들웨어를 구현할것이다.

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(function(req,res,next) {
  console.log(req.url, '저도 미들웨어입니다.');
  next();
});

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.set과 app.use 사이에 새로운 미들웨어를 추가해줬다.

app.js를 저장하고 서버를 실행, 그리고 브라우저창에 주소를 입력하여주면

콘솔에 다음과 같이 입력된다.

요청두개, 즉 GET /GET /stylesheets/style.css가 서버로 전달되었다. 각각의 요청을 통해 커스텀 미들웨어를 작동시켰다.

이렇게 서버가 받은 요청은, 미들웨어를 타고 라우터까지 전달된다.

다만 주의해야할 점은, 반드시 미들웨어 안에서 next()를 호출해야만 다음 미들웨어로 넘어간다.

logger, express.json ... 등은 모두 내부적으로 next()를 호출하기때문에 따로 작성하지 않아도 다음 미들웨어로 넘어갈 수 있다. next()는 미들웨어의 흐름을 제어하는 핵심적인 함수이다!

여기서 next 함수 몇가지 기능이 더 있다. 인자의 종류에 따라 기능이 구분되는데, 구분되는 기능은 다음과 같다.

  • 인자를 아무것도 넣지 않는 경우 : 단순히 다음 미들웨어로 넘김

  • 인자로 route를 넣어줌 : 다음 라우터로 이동

  • route 외에 다른 값을 넣어줌 : 미들웨어나 라우터를 건너뛰고 바로 에러핸들러로 이동
    (넣어준 값은 에러에 대한 내용으로 간주)

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

해당 코드가 에러 핸들링이 되는 부분이다. 라우터에서 요청이 처리되지 않으면(일치하는 주소가 없다면) 이 미들웨어로 넘어오게 된다.

http-errors(createError) 패키지404 에러를 만들어내고, 이 에러를 next에 담아 에러핸들러로 보내준다.

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

이 미들웨어는, 다른 미들웨어와 다르게 4개의 함수 매개변수를 가지게 되는데, err라는 매개변수가 새로 추가되었다.

next 함수에 넣어준 인자가 err 매개변수로 연결되는데, 에러 핸들링 미들웨어는 일반적으로 미들웨어 중 가장 아래에 위치하여 위에 있는 미들웨어에서 발생하는 에러를 받아서 처리한다.


📝 morgan

콘솔에 나오는 GET / 304 1042.151 ms - - 같은 로그는 모두 morgan 미들웨어에서 나온다. 해당 미들웨어는 요청에 대한 정보를 콘솔에 기록해준다.

함수의 인자로는 dev가 입력되어있는데, 인자에 따라 콘솔에 나오는 로그가 다르다.

dev인 경우

HTTP 요청(GET) + 주소(/) + HTTP 상태코드 + 응답속도 + 응답바이트

순으로 출력된다.

보통 개발에서는 short와 dev를, 배포시에는 common이나 combined를 많이 사용한다.


📝 express-session

세션 관리용 미들웨어로, 로그인 등의 이유로 세션을 구현할때 유용하다.

해당 미들웨어는 express-generator로 설치되지 않으므로 다음 코드로 설치해야한다.

npm i express-session

설치 후 app.js에 express-generator를 연결해준다.

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({
  resave: false,
  saveUninitialized: false,
  secret: 'secret code',
  cookie: {
    httpOnly: true,
    secure: false,
  },
}));
app.use(flash());

app.use('/', indexRouter);
app.use('/users', usersRouter);

이렇게 작성해주면 된다~~~

express-session은 인자로 세션에 대한 설정을 받는다.

  • resave : 요청이 왔을때 세션에 수정 사항이 생기지 않더라도 세션을 저장할지?

  • saveUninitialized : 세션에 저장할 내역이 없어도 저장할지? (방문자 추적시 사용)

  • secret : 필수항목으로, cookie-parser의 비밀키와 같은 역할

  • cookie : 세션 쿠키에 대한 설정

    • httpOnly : 클라이언트에서 쿠키를 확인하지 못하게 설정
    • secure : false일 경우 http가 아닌 환경에서도 사용 가능
      (배포시에는 https를 적용하고 true로 변경하는게 좋음)

express-session은 세션 관리시 클라이언트에 쿠키를 보내게 되는데, 이를 세션 쿠키라고 한다. 안전하게 쿠키를 전송하려면 쿠키에 서명을 추가해야 하고, 쿠키를 서명하는데 secret값이 필요하다.

cookie-parsersecret과 같게 설정해야 한다.

profile
안녕하세요

0개의 댓글