나의개발일지
[Express] express는 Middleware가 엄청나게 많다. 와 middleware야 너는 정말 좋겠구나 본문
[Express] express는 Middleware가 엄청나게 많다. 와 middleware야 너는 정말 좋겠구나
kdy9kdy 2023. 1. 20. 22:38
본 글은 작성자가 어디선가 주워듣고 이해한 내용들을 개인적인 언어로 작성한 게시물입니다.
잘못된 내용이 존재할 수 있으니, 읽게 되신다면 이점을 감안해 주세요!!!
- 우리는 결국 자신이 가진 이야기로 상대방을 이해할 수 있을 뿐이다.-
express는 정해진 틀이 존재하지 않는 것 같다. django와 비교해서 좀 더 자유롭다고 느끼는 한편 내가 직접 설정을 해주거나 해야 하는 부분도 존재한다고 한다. 그중 하나가 middleware인 것 같다. 직접 middleware를 설정해주어야 한다는데, 복잡한 느낌이 들긴 한다. 그런데 middleware라는 게 복잡한 거기도 하고 알고 보면 간단한 기능을 수행하는 것도 middleware라고 해서 아직은 개념이 애매한 느낌이다. 그래서 이번 포스팅에서는 middleware에 대해서 조금 알아보고자 한다.
내가 사용한 middleware가 있다고??
이전 포스팅 글에서는 express를 이용해서 간단한 CRUD를 작성했는데, CRUD를 작성하는 코드 중에도 middleware가 있다고 한다. 미들웨어 중 하나가 req.body를 파싱해주는 코드였다.
app.use(express.urlencoded({extended:true}));
위의 코드도 express에 있는 미들웨어라고 한다. 위의 기능을 요청이 들어오면 해당 요청의 body에 내용이 있는 경우 파싱해서 body에 데이터를 채워주는 역할을 한다. 미들웨어는 중간에서 어떤 역할을 하는 함수를 말하는 것인 거 같다(?)
미들웨어???
미들웨어란 요청-응답의 생명주기 내에서 실행되는 함수라고 한다. 요청이 와서 코드를 처리하고 응답을 보낼때까지 실행되는 것이다. 또한 요청과 응답사이에 실행되는 함수이고, 요청객체와 응답객체에 접근할 수 있다. 미들웨어는 요청-응답 주기를 종료할 수도 있고, 응답을 돌려보낼 수도 있고, 연쇄적으로 연결된 다른 미들웨어를 호출할 수도 있다. 미들웨어는 Express 내 함수로 Express 내 모든 것에 접근할 수 있다. 라우터핸들러도 일종의 미들웨어이다. 간단한 미들웨어를 직접 작성해 보자!!!
const express = require("express");
const app = express();
app.use(()=>{
console.log("i am middle ware");
})
app.get("/homepage", (req,res)=>{
res.send("homepage입니다")
})
app.listen(3000, ()=>{
console.log("SERVING 3000 PORT");
})
위의 코등 중 app.use()에 해당하는 부분이 미들웨어이다. 요청으로 /homepage에 요청이 들어올 경우 먼저 app.use가 실행되게 된다. 하지만 위의 코드를 실행하면 홈페이지로 응답받을 수 없다. i am middle ware를 출력 후 대기 상태가 된다. 응답이 끝나지 않는다. 그렇기 때문에 미들웨어를 정의하는 문법을 이용해서 미들웨어를 사용해야 한다.
// 함수를 미들웨어로 정의하고 싶다면 위와 같이 작성하면 된다. (req,res,next)
// next를 호출함으로써 미들웨어나 라우트 핸들러를 호출할 수 있다.
// 위의 경우는 next를 호출하지 않았기 때문에 어떠한 요청이 들어오든 위의 요청에서 다음으로 넘어가지 않는다.
// 아래와 같이 next를 호출해주어야지 /homepage를 호출할 수 있게 된다.
app.use((req,res,next)=>{
console.log("첫번째 미들웨어에 next추가")
return next();
})
// 만약 위의 첫번째 미들웨어에서 next를 호출하지 않으면 아래로는 내려올 수 없다.
app.use((req,res,next)=>{
console.log("두번째 미들웨어에 next추가")
return next();
})
미들웨어를 정의하기 위해서는 (req, res, next) 3개의 인수를 전달해야 한다. 여기서 중요한 것이 next로 next를 이용해서 다음 기능을 계속 수행하게 한다. next()를 이용해서 다음 미들웨어를 호출할 수도 있고, 아니면 /homepage에 해당하는 라우트핸들러를 호출할 수도 있다.
미들웨어에 데이터 조작
미들웨어는 req, res의 객체에 접근할 수 있다. 그렇기 때문에 req나 res의 데이터에 대한 선/후 작업이 가능하다. 들어오는 요청에 대해서 시간데이터를 추가하고 싶다고 한다면, 다음과 같은 코드를 이용해서 추가해 줄 수 있다.
// 라우트 핸들러가 실행되기 전에 요청객체에 접근해서 데이터에 대한 조작을 하는 미들웨어
app.use((req,res,next)=>{
req.requestTime = Date.now();
next()
})
app.get("/homepage", (req,res)=>{
console.log(req.requestTime)
res.send("home page")
})
위와 같이 라우트 핸들러에서 미들웨어에서 정의한 requestTime이라는 데이터에 접근을 할 수도 있다. 이와 같은 데이터 접근은 인증/인가를 처리하는 auth 기능에서 유용하게 사용할 수 있다. 간단한 패스워드 확인 미들웨어를 작성해서 어떻게 이용되는지 알아보도록 하자!!
미들웨어 - Password가 필요해
//비밀번호 설정하는 데모 만들기
app.use((req,res,next)=>{
const {password} =req.query;
if (password === "password"){
next();
}
res.send("You need Passowrd")
})
//localhost:3000/homepage?password=password
use는 어떤 요청이 들어오던지 먼저 수행된다. 간단한 구현을 위해서 password를 쿼리 스트링으로 받는다. req객체에 접근할 수 있기 때문에 req에서 password를 확인 후 해당 password가 맞다면 다음을 next()를 호출하고 아니면 미들웨어에서 요청을 종료시킨다. 간단한 구현이기 때문에 적절한 로직은 아니지만, 인가/인증을 구현하는 방법은 위와 같이 미들웨어를 이용해서 로직을 구현하게 된다. 하지만 위에 정의된 미들웨어의 경우 모든 요청에 대해서 password를 확이하게 된다. 이때, 특정 라우트 핸들러에만 password를 요청하게 할 수 있다. 두 가지 방법이 있는데, 첫 번째 방법은 use() 이후에 특정 url을 적는 것이다.
//비밀번호 설정하는 데모 만들기
app.use("/homepage", (req,res,next)=>{
const {password} =req.query;
if (password === "password"){
next();
}
res.send("You need Passowrd")
})
특정 주소를 입력하여 해당 주소로 요청이 들어올 경우만 비밀번호를 확인하는 로직이 완성된다. 하지만 이 방법을 이용하게 된다면 다수의 주소에 비밀번호를 요청하는 로직을 사용하기에는 불편함과 어려움이 있다. 그렇기 때문에 보통은 아래와 같은 방법을 사용한다.
함수로 정의하고 콜백함수를 전달하자
// 함수로 정의하자!!
const checkPassword = (req,res,next)=>{
const {password} =req.query;
if (password === "password"){
next();
}
res.send("You need Passowrd")
}
// 정의된 함수를 콜백함수로 전달하자!!
app.get("/homepage", checkPassword, (req,res)=>{
res.send("if you can see this page, you check password before enter this page")
})
위와 같이 미들웨어를 정의한 뒤 비밀번호가 필요한 라우터 핸들러에 콜백함수로 전달하는 것이다. 그러면 해당 라우터에 대한 요청이 들어올 경우 위에서 정의된 함수가 실행되게 되고, 해당 함수는 미들웨어이기에 password가 맞다면 next()를 호출해서 요청이 끝날 수 있게 된다.
정리하자면
사실 지금 내가 정리한 내용은 기초 중에 기초에 해당한다. 정말 간단한 미들웨어만을 정의해서 어떤 식으로 작동하는지 알기 위한 코드에 지나지 않다. 하지만, 미들웨어라는 함수가 어떤 식으로 정의되고, 어떤 흐름으로 작동하는지에 대한 설명으로는 괜찮은 거 같다. 미들웨어를 직접 정의하는 것 이외에도 제공되는 middleware도 많기 때문에 필요에 따라 해당 미들웨어를 찾아서 적절히 사용하면 좋을 거 같다.
본글은 작성자의 사견이 포함된 글입니다.
잘못된 내용이 다수 존재할 수 있음을 유의해서 참고해 주세요
재미있다 재미있다 재미있다....
'NodeJS.Express.MongoDB' 카테고리의 다른 글
| [Joi] 유효성 검사를 해 볼까????? 해보자!!!!!! (0) | 2023.01.21 |
|---|---|
| [Express] 알아보자!! Error-handler 사용하자!! Error-handler 포기하자..... (1) | 2023.01.20 |
| [nodeJS+Express+mongoose] 연결하자 연결하자!!!! (0) | 2023.01.20 |
| [mongoose] mongoDB를 node에서 사용해보자!!! (0) | 2023.01.17 |
| [mongoDB] 기초적인 mongoDB를 시작해보자!!! (0) | 2023.01.17 |