express 미들웨어

chu·2021년 3월 24일
0

이번 시간에는 express를 사용하면서 여러 미들웨어에 대해서
정리를 해본다.


미들웨어란?

공식문서

Express 애플리케이션은 기본적으로 일련의 미들웨어 함수 호출입니다.

미들웨어 함수는 요청 오브젝트(req), 응답 오브젝트 (res), 그리고 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수 대한 액세스 권한을 갖는 함수입니다.

그 다음의 미들웨어 함수는 일반적으로 next라는 이름의 변수로 표시됩니다.

간단하게 코드로 확인해보자.

const express = require('express');
const app = express();

// 이런 영역이 있다면
app.get('/', (req, res, next) => {
  res.send();
  next();
});

// 바로 이 부분이 미들웨어라고 공식문서에는 말하는것 같다
(req, res, next) => {
  res.send();
  // 다음 미들웨어 호출
  next();
});

물로 위 부분만이 미들웨어는 아니다. 미들웨어는 많다.
그 중에서도 자주 쓰이는 미들웨어도 있고, 특정한 작업에만
필요한 미들웨어도 있을 것이다. 하지만 이 시간에는
그런 특정한 부분까지 다루지는 않는다.

자주 쓰이는 미들웨어를 확인해보자!

morgan

npm i morgan

요청이 들어오거나, 에러가 발생하거나 어떤 서버와 관련된
어떠한 행위를 터미널에 로깅 해주는 미들웨어

const morgan = require('morgan');

// 일반 사용 시 - dev : 개발모드
app.use(morgan('dev'));

// 일반 사용 시 - combined : 배포 모드
/*
   dev모드 보다 더 자세한 내용을 알려준다.
   ex) IP주소, 접속한 브라우저 등...
*/
app.use(morgan('combined'));

이 외에도 미들웨어를 좀 더 다르게 사용하기 위해 확장을 시킬 때도 있다.

미들웨어 확장법

로깅할 때 쓰이는 morgan을 예시로 작성해보겠다.

const morgan = require('morgan');

// 일반 사용 시 - dev : 개발모드
app.use(morgan('dev'));

// 미들웨어 확장법 1
app.use((req, res, next) => {
  morgan('dev')(req, res, next);
});

// 미들웨어 확장법 2
app.get('/', (req, res, next) => {
  if (process.env.NODE_ENV === 'production'){
    morgan('combined')(req, res, next);
  } else {
  	morgan('dev')(req, res, next);
  }
});

npm i cookie-parser

cookie란?
우리는 로그인을 했고, 탭을 닫고 다시 들어가면 로그인은 풀려있는 아주 안좋은 상황이라면, 내가 로그인을 하고 있는 중이다 라는 것을 서버에 알릴 수 있으면 얼마나 좋을까?

이것을 해결해주는 것이 쿠키다.

cookie-parser는 쉽게 쿠키를 추출할 수 있는 미들웨어다.
설치를 하게되면 express의 req로 제공을 해준다.

express-session

npm i express-session

위에서 쿠키에 대해서 정리를 해봤다.
하지만 쿠키는 브라우저 개발자 도구에서 쉽게 확인이 가능하다.
즉, 보안상 위험이 있는 것이다.

이것을 더욱 안전하게 만들어주는 것이 express 내부에서
제공되는 미들웨어 session(세션)이다.

const express = reuqire('express');
const session = require('express-session');

app.use(session({
  resave: false, 
  saveUninitialized: false, 
  secret: process.env.COOKIE_SECRET,
  cookie: { 
    httpOnly: true, 
  },
}))

resave
요청이 올 경우 세션에 수정사항이 생기지 않아도 다시 저장할지 여부

saveUninitalized
세션에 저장할 내역이 없더라도 세션을 저장할지 여부

secret
cookie-parser에서 설정한 환경변수 키

cookie
여기서 말하는 쿠키는 sessionCookie다

cookie : {httpOnly: true}
javascript 공격 방어 (보안)

express-static

express에서 제공하는 미들웨어이다.
static은 html, css 등 정적 파일을 제공해준다. 또한
보안에도 도움을 준다.

const express = require('express');
const path = require('path'); // 경로설정
const app = express();

// app.use('요청경로', express.static(path.join(실제경로)));

app.use('/', express.static(path.join(__dirname, 'public')));

위와 같이 작성하면 된다. 여기서 public은 실제 존재하는
폴더여야 한다. 이렇게 작성해서 보안에 어떻게 도움을 줄까?

// example
localhost:3000/index.js // 요청 경로

node/public/index.js // 실제 경로

요청 경로만 본다면 로컬호스트 다음 바로 index.js가 위치하고 있을거라 생각들지만, 실제로는public이라는 폴더가 있기 때문이다.

그럼 이런 기능은 어디서 사용을 해야할까?

예를 들면 클라우드처럼 로그인을 해야만 유저에게 해당되는 데이터를 보여줄 수 있어야 하는 곳.

그럴땐 미들웨어 확장법을 사용하여 기능을 추가해준다.

app.use((req, res, next) => {
  // req.session에 id가 있다면
  if (req.session.id) {
    express.static(path.join(__dirname, 'public'))(req, res, next);
  } else {
    next();
  }
})

multer

multer는 이미지, 동영상 등 파일을 업로드 할 때 쓰인다.

multer 자체가 미들웨어라기 보단, 안에 있는 네가지의 기능의 미들웨어가 들어있다.

특히 form 태그의 속성 중 enctype="multi/form-data"인 경우에 쓰인다.

// multer 설정
const upload = multer({
  // 저장위치
  storage: multer.diskStorage({
    // 어디에 저장할지
    destination(req, file, done) {
      done(null, 'uploads/');
    },
    filename(req, file, done){
      // 불러온 file 명 가져오가
      const ext = path.extname(file.originalname); 
      // 파일 이름 변경 (중복없이)
      done(null, path.basename(file.originalnamem, ext) + Date.now() + ext); 
    },
  }),
  // 5메가바이트 이하만, 이상이면 400번대 에러 발생
  limits: { fileSize: 5 * 1024 * 1024 },
});

설정을 했으면, 적용을 해보자.

<form enctype="multi/form-data">
  <input type="text" name="image" />
</form>
const express = require('express');
const app = express();

app.post('/upload', upload.single('image'), (req, res) => {
    console.log(req.file);
    res.send('ok');
});

upload 변수에 multer를 설정했다.
app.post에서 single()이라는 미들웨어를 사용했다.

single() - 하나의 파일만 업로드 할 수 있다.
array() - 한번에 여러 파일을 업로드 할 수 있다.
fields() - 여러번 선택하여 여러 파일을 업로드 할 수 있다.
none() - 아무것도 업로드 하지 않는다.

여기서 single()안에 들어간 imageinput 태그의 name과 동일해야한다.

또한 console.log(req.file)는 업로드한 정보를 담고 있다. 그 중 file은 multer의 어떤 미들웨어를 사용했는지에 따라 다르게 작성해야된다.

single() - req.file
array() - req.files
fields - req.files.name명

아직 부족한게 많은 정리입니다.
강의를 듣고, 내용을 정리하고, 부족한 내용은 블로그나
공식문서를 통해 정리하려고 합니다.

부족한 점 있다면, 알려주시면 감사하겠습니다 👏😭

profile
한 걸음 한걸음 / 현재는 알고리즘 공부 중!

0개의 댓글