express

ClassBinu·2024년 4월 4일

Node.js 교과서

목록 보기
11/19

express

node에서 res.write(), res.end()로 하던 걸 res.send()로 간단하게 처리 가능
라우팅을 if문으로 분기처리 했던 걸 app.get('/', 라우터); 형태로 할 수 있음.

미들웨어

요청과 응답의 중간에 위치함.
익스프레스의 핵심.

미들웨어는 app.use(미들웨어) 구문으로 사용함.

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("에러는 에러 처리 미들웨어로 갑니다.");
  }
);

// 이건 express가 자동으로 에러 처리 미들웨어로 인식함.
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"), "번 포트에서 대기 중");
});

기본적으로 인수가 4개인 app.use는 에러 처리 미들웨어로 인식한다.

미들웨어 실행

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

주요 미들웨어

morgan

로거

static

express 내장 모듈

body-parser

요청 본문 데이터를 req.body 객체로 만들어주는 미들웨어
express 기본 내장
멀티파트(이미지, 동영상, 파일) 데이터는 처리 불가 -> 이건 multer 모듈 사용

app.use(express.json()); // // 요청 본문의 JSON 문자열을 파싱하여 req.body에 객체 형태로 들어감.
app.use(express.urlencoded({ extenede: false })); // URL-encoded 형태의 요청 본문을 파싱하여 req.body에 객체 형태로 들어감.

body-parser를 쓰면 스트림을 일일이 처리하지 않아도 내부적으로 알아서 처리함.

요청에 동봉된 쿠키를 해석해 req.cookies 객체로 만듦.
유효기간이 지난 쿠키는 알아서 걸러냄.

app.use(cookieParse(비밀 키));

쿠키는 res.cookie(키, 값, 옵션) 형식으로 사용함.

res.cookie('name', 'classbinu', {
  expires: new Date(Date.now() + 3600),
  httpOnly: true,
  secure: true,
}));
res.clearCookie('name', 'classbinu', { httpOnly: true, secure: true });

쿠키를 지우려면 키, 값, 옵션이 정확히 일치해야 함.
단, expires, maxAge는 일치할 필요 없음.

signed옵션을 true로 설정하면 쿠키 뒤에 서명이 붙으며, 내 서버에서 만든 쿠키라는 걸 인증할 수 있음.

// cookie-parser에 서명 키를 전달하여 서명된 쿠키를 파싱할 수 있도록 설정
app.use(cookieParser(process.env.COOKIE_SECRET));

app.get('/set-cookie', (req, res) => {
  // 서명된 쿠키 설정
  res.cookie('name', 'John Doe', { signed: true });
  res.send('Signed cookie has been set');
});

app.get('/get-cookie', (req, res) => {
  // 서명된 쿠키 접근
  // 서명된 쿠키는 req.signedCookies 객체를 통해 접근 가능
  const name = req.signedCookies.name;
  if (name) {
    res.send(`Cookie value: ${name}`);
  } else {
    res.send('Signed cookie is not found or signature is invalid');
  }
});

서명이 쿠키 자체를 암호화하는 건 아님!
무결성 검증을 위해 별도 해싱된 서명을 보내는 것!
즉, 클라이언트로부터의 쿠키 변조 여부를 체크하는 것.
그렇지 않으면, 임의로 조작된 쿠키가 넘어오는 걸 수도 있음.
다만 이 경우에도 쿠키와 서명이 모두 탈취된다면 다른 이가 인증을 속일 수 있음.

express-session

세션 관리용 미들웨어
세션은 사용자별로 req.session 객체에 유지

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

기본적으로 서버는 클라이언트의 상태를 기억하지 못한다.
그걸 기억할 수 있는 방법이 '세션'인데,
이 모듈을 통해 세션을 쉽게 생성하고 관리할 수 있게 해 준다.

express-session의 주요 역할:

  • 세션 생성 및 관리: 사용자가 웹 사이트에 처음 방문할 때, express-session 미들웨어는 고유한 세션 ID를 생성하고 이를 사용자의 브라우저에 쿠키로 전송합니다. 이 세션 ID는 이후 사용자의 모든 요청에 포함되어 서버로 전송되며, 서버는 이 ID를 통해 해당 사용자의 세션을 식별합니다.

  • 세션 데이터 저장: 사용자의 로그인 상태, 쇼핑 카트 내용 등과 같은 세션 데이터를 서버 측에 저장합니다. express-session은 메모리, 파일, 데이터베이스 등 다양한 저장소에 세션 데이터를 저장할 수 있는 옵션을 제공합니다.

  • 세션 만료 및 삭제: 세션이 일정 시간 동안 사용되지 않거나, 사용자가 로그아웃할 때 세션을 만료시키고 삭제합니다. 세션 만료 시간은 설정할 수 있으며, 이를 통해 미사용 세션을 자동으로 정리할 수 있습니다.

쿠키는 꼭 세션에서만 사용되는 건 아님!

세션에 사용되는 쿠키를 특별히 '세션 쿠기'라고 하지만 쿠키는 다양하게 활용 가능함.

  1. 사용자 인증
    웹 사이트에서 로그인 후 사용자의 인증 정보(예: 로그인 상태)를 저장하는 데 쿠키를 사용합니다. 이를 통해 사용자가 웹 사이트를 탐색할 때 마다 로그인을 반복하지 않아도 되는 편리함을 제공합니다.
  2. 사용자 설정
    사용자의 선호도나 설정(예: 언어 설정, 테마 선택)을 저장하여, 사용자가 웹 사이트를 재방문할 때 동일한 설정을 적용할 수 있게 합니다.
  3. 추적 및 분석
    사용자의 웹 사이트 사용 패턴과 행동을 추적하기 위해 분석 쿠키를 사용합니다. 이 정보는 웹 사이트의 사용성 개선, 마케팅 전략 수립, 사용자 맞춤형 콘텐츠 제공 등에 활용될 수 있습니다.
  4. 광고 타게팅
    사용자의 관심사와 웹 브라우징 행동을 기반으로 맞춤형 광고를 제공하는 데 쿠키를 사용합니다. 이를 통해 광고주는 더 높은 전환율을 기대할 수 있습니다.
  5. 임시 데이터 저장
    양식 데이터 자동 완성, 쇼핑 카트 아이템 저장 등 사용자가 입력한 정보를 임시로 저장하고, 사용자가 웹 사이트를 탐색하는 동안 지속적으로 이 정보를 이용할 수 있게 합니다.

미들웨어 정리

자, 미들웨어는 함수다.
근데 매개변수로 req, res, next를 갖는다.
다만 에러 처리 미들웨어만 err, req, res, next를 갖는다.

app.use(), app.get(), app.post() 등으로 미들웨어를 장착할 수 있다.
특정한 주소의 요청에만 미들웨어가 실행되게 하려면 첫 번째 인자로 주소를 넣으면 된다.
여러 개의 미들웨어를 동시에 장착할 수도 있다.
다음 미들웨어로 넘어가려면 next()를 호출한다.
next()를 호출하지 않을 거면 res.send, res.sendFile 메서드로 응답을 보내야 한다.
장착 순서에 따라 미들웨어 일부가 실행되지 않을 수도 있다.
(예를 들어 정적 파일 제공 미들웨어에서는 express.json, urlencoded, cookieParser 실행 안 됨)

next()도 안하고 응답도 안하면 클라이언트는 계속 기다리다가 타임아웃한다.

0개의 댓글