본문 바로가기
○ WEB/19.10 NomadCoder_Youtube Clone

4. middleware, morgan, helmet, body-parser

by 0ver-grow 2019. 10. 9.
반응형

미들웨어

처리가 끝날 때까지 연결된 것

어떻게 연결됐는가 request가 어떻게 시작되는가
시작은 브라우저에서 부터, 웹사이트에 접속하려할때이다.
index.js파일을 실행하면 해당 route가 존재하는지 보고 있으면 해당 콜백함수를 실행한다.

보통 유저와 마지막응답 사이에 뭔가가 존재한다.
이를 미들웨어라고 한다.

express에서 모든 함수는 미들웨어가 될수있다. 
예를들어, app.get("/", handleHome); 는 유저가 home('/')요청을 하면 handleHome콜백함수가 실행이 되는데
이 사이에 미들웨어 함수(betweenHome)을 만들어 넣어보면 어떻게 될까?

app.get("/",betweenHome,handleHome);이면 유저가 home('/')요청을 하면
betweenHome 콜백함수가 먼저 실행되고 그 후 handleHome함수가 실행된다.

그러나 브라우저로 부터 온 요청을 계속 처리할지에 대한 권한을 주지 않았다.
그래서 next라는 키를 써야한다.
next키는 미들웨어함수에서만 사용한다.

return만 하는
마지막 함수에는 next키를 사용하지 않는다. 
express의 모든 루트는 connection을 다룰 때, req,res,next를 가지고 있다. 

미들웨어를 통해 유저의 로그인 여부, 파일전송시 중간에서 가로채기, 로그를 남기고 싶을 때 사용한다. 

만약에 미들웨어에도 똑같이 res.send가 있으면 마지막함수의 res.send가 아닌 미들웨어의 res.send가 나타난다.

전역적 미들웨어

그런데 위 처럼 작성하면 미들웨어를 삽입한 "/"에서만 미들웨어가 동작한다.
웹사이트에 일어나는 모든 것에 미들웨어가 동작하게 하려면 다음과 같이 전역적 미들웨어로 바꿔주면 된다.
전역적 미들웨어를 사용해야 미들웨어 동작후 루트가 반환된다. 
단, app.use(미들웨어) 의 위치가 굉장히 중요하다. JS는 위에서 아래로 동작하기 떄문이다.
만약 여러 미들웨어를 웹 전체에 적용하고 싶다면 app.get전에 여러 미들웨어 전부를 써야 한다.

만약 app.get("/",handleHome)이 app.use(betweenHome)보다 위에 있으면 홈("/")에선 미들웨어가 동작하지 않고 /profile에서만 동작하게 된다. 


미들웨어 종류

morgan

로깅할 때 사용하는 미들웨어
npm install morgan

Error >>>
morgan을 설치한 다음부터 package.json을 저장하면 나타나는 에러.
그러나 morgan만 그런것이 아니었다.
Failed to save 'package.json': The content of the file is newer. Please compare your version with the file contents.
Process>>>
npm홈페이지에 나와있는대로 npm i morgan으로 설치를 진행했더니 이전에 발생했던 오류는 생기지 않았지만 dependencies에도 morgan이 없다.

이 다음 미들웨어인 helmet도 홈페이지에 나온대로 npm i helmet으로 설치를 했으나 dependencies에 helmet이 없다. dependencies에 직접 적어서 넣어보도록하자.
그러나, npm install body-parser와 npm install cookie-parser를 하니 또 동일한 오류인 "The content of the file is newer"가 발생했다.

Solution >>> package.json 파일을 삭제한 뒤, 다시 npm init을 해줬더니
dependencies에 body,cookie,express,helmet,morgan이 존재했고, 저장해도 오류가 생기지 않았다. 제대로 반영이 안되서 발생한 문제.
- 처음만난 문제를 해결하기 위해 구글링하고, 모듈 삭제 및 재설치하고 새 프로젝트를 만들어 다시 처음부터 만들어보면서 뒤져보고 깃헙에 올린 코드를 다시 살펴보면서 시행착오를 기록하다보니 벌써 2시간이 지나 새벽 3시 반이 넘었다... 그래도 끝냈다. 목표완수.

그냥 저 빨간색화살표만 눌러주면된다.

helmet

노드 보안에 필요한 미들웨어이다.
npm install helmet


body parser

바디 다루는걸 도와주는 미들웨어
npm install body-parser
누군가 form(아이디,비번 등)을 나에게 전송했다면 이 form은 서버에 의해 받아져야만 한다.
이 form을 받았을 때 request object에 접근할 수 있어야 하는데 이 때 쓰이는 것.
그러나 body-parser에는 정의해야할 옵션이 있다. 
그중 json, text, urlencoded 등을 알아야 무엇을 전송했는지 알 수 있다.
만약 json을 전송했다면 서버가 json을 이해하길 바래야하며, 일반적인 html form을 전송했다면 서버가 urlencoded라는 걸이해하길 바래야한다.
이게 서버가 유저로부터 받은 데이터를 이해하는 방법이다. 유저로부터 받은 쿠키를 이해하는 방법이다. 

cookie parser

쿠키다루는걸 도와주는 미들웨어
npm install cookie-parser
쿠키에 유저 정보를 저장한다. 왜냐? session을 다루기위해서

Error >>>
지금까지 npm install *을 해주면 *은 dependency에 자동추가되었지만
하단의 cookie-parser, body-parser는 추가되지 않았다. 수동으로 해줘야 하는가?

Solution >>>
그렇다. VSCode에서 우측하단의 팝업창으로 에러를 알려주고 그에 맞게 넣어주면된다.

 

미들웨어로 미들웨어 연결을 끊을 수 있다.

다음코드를 추가하자.

import express from "express";
import morgan from "morgan"; // 로깅하기_모슨일을했는지 기록 어떤접속이고 어디에접속하는지알수있음
import helmet from "helmet";
import cookieParser from "cookie-parser";
import bodyParser from "body-parser";

app.use(cookieParser()); // 쿠키에 유저 정보를 저장한다. 왜냐? session을 다루기위해서
app.use(bodyParser.json()); // form을 다룰수있어야한다.
app.use(bodyParser.urlencoded({extended:true})); // form을 다룰수있어야한다.
app.use(helmet()); // 노드 보안 미들웨어
app.use(morgan("dev"));  // 모든 것을 로깅(기록)하는 미들웨어
추가한 모습은 하단과 같다.

import express from "express";
import morgan from "morgan"; // 로깅하기_모슨일을했는지 기록 어떤접속이고 어디에접속하는지알수있음
import helmet from "helmet";
import cookieParser from "cookie-parser";
import bodyParser from "body-parser";

const app = express()
const port = 4000;

const handleListening= () =>
    console.log(`Listening on : http://localhost:${port}`);

const handleHome = (req,res) => res.send("god Home!"); // 마지막 함수이기에 next키가 없다.
const handleProfile = (req,res) => res.send("What'up man");

app.use(cookieParser()); // 쿠키에 유저 정보를 저장한다. 왜냐? session을 다루기위해서
app.use(bodyParser.json()); // form을 다룰수있어야한다.
app.use(bodyParser.urlencoded()); // form을 다룰수있어야한다.
app.use(morgan("combined"));  // globally middleware
app.use(helmet());

const middleware = (req,res,next) => { // 미들웨어로 미들웨어 연결을 끊을수있다
    res.send("NoNoNo");
}

app.get("/",middleware,handleHome); // 미들웨어를 끊어보자
app.get("/profile",handleProfile);
app.listen(port, handleListening);
반응형