SeSAC x CodingOn 웹 취업 부트캠프

[새싹/코딩온] 풀스택 웹 개발자 취업 부트캠프 7주차 (1): Cookie & Session

haeriyouu 2025. 1. 4. 21:25

🍪Cookie🍪

  • 웹 브라우저(클라이언트)에 저장되는 키와 값이 들어있는 작은 데이터 파일
    • 클라이언트 측에 저장되므로 보안에 취약할 수 있다!
  • 이름, 값, 만료일, 경로 정보로 구성되어 있다.
더보기
   <script>
      console.log("doc.cookie", document.cookie);
      // 프론트에서 쿠키 설정
      document.cookie = "user=sesac; expires=09 Dec 2024 /15:00:00 GMT; path=/";
    </script>
// 백엔드 쿠키 설정
// cookie.js

const express = require("express");
const cookieParser = require("cookie-parser");
const app = express();
const PORT = 8080;

// ver1. 암호화 되지 않은 쿠키
// app.use(cookieParser());

// ver2. 암호화된 쿠키
// 실제로 암호화 쿠키를 사용한다면 비밀키도 .env로 관리하는 것이 좋다. 문자열은 아무거나 상관 없음
app.use(cookieParser("password"));

app.set("view engine", "ejs");

// 쿠키 설정 객체
const cookieConfig = {
  // maxAge: 쿠키의 수명, 1000이 1초인 밀리초 단위로 설정 ex) 1000*60*5 = 5분
  // expires: 만료 날짜, GMT 시간 설정 ex) new Date(2024, 11, 9)
  // httpOnly: 프론트에서 document.cookie로 접속하는 것을 차단, http 통신으로만 접근 가능 (true/false)
  // path: '/', '/abc' 등 원하는 경로에서 쿠키 설정 가능
  // secure: 웹 브라우저와 웹 서버가 https로 통신할 경우에만 쿠키 전송 (true/false)
  // signed: 쿠키 암호와 여부 (true/false)
  maxAge: 10 * 60 * 1000, // 수명 10분
  httpOnly: true, // 프론트에서 쿠키 접근 막기
  // signed: false, //ver1.
  signed: true, // ver2. 암호화된 쿠키
};

const cookieConfig2 = {
  maxAge: 10 * 60 * 1000,
  httpOnly: true,
  path: "/abc",
};

app.get("/abc", (req, res) => {
  res.cookie("abc-page", "abc-page cookie", cookieConfig2);
  res.render("cookie-another");
});

app.get("/", (req, res) => {
  res.render("cookie");
});

app.get("/getCookie", (req, res) => {
  console.log(req.cookies); // {쿠키: 쿠키 값, ...}
  console.log("암호화된 쿠키", res.signedCookies);
  // res.send(req.cookies); // ver1. 암호화 되지 않은 쿠키
  res.send(req.signedCookies); // ver2. 암호화 된 쿠키
});

// 쿠키 설정
app.get("/setCookie", (req, res) => {
  // res.cookie(쿠키이름, 쿠키값, 쿠키 옵션)
  res.cookie("myCookie", "내가구운쿠키~~~~", cookieConfig);
  // 암호화된 쿠키 / 암호화 되지 않은 쿠키
  // 모두 res.cookie()로 쿠키 설정
  res.send("set cookie 완료, 응답 종료!");
});

app.get("/clearCookie", (req, res) => {
  res.clearCookie("myCookie", "내가구운쿠키~~~~", cookieConfig);
  res.send("clear cookie, 응답 종료!");
});

app.listen(PORT, () => {
  console.log(`http://localhost:${PORT}`);
});
 ver1. 암호화 하지 않았을 때
 - middleware -> app.use(cookieParser())
 - 쿠키설정 -> res.cookie(쿠키 이름, 쿠키 값, 쿠키 옵션 객체)
 - 쿠키 확인 -> req.cookies 객체에서 확인
 - 쿠키 삭제 -> res.clearCookie(쿠키 이름, 쿠키 값, 쿠키 옵션 객체)
 - clearCookie(), cookie()는 응답 완료를 하지 않음 -> 이후에 render, send, redirect, end, etc. 등으로 응답 완료 작업을 해야 함
          -> 삭제할 때는 이름, 값, 옵션이 일치해야 삭제 가능.
 
 ver2. 암호화 했을 때
 - middleware -> app.use(cookieParser('임의의 문자열'))
 - 쿠키설정 -> res.cookie(쿠키 이름, 쿠키 값, 쿠키 옵션 객체) // ver1.과 동일
          -> 단, 쿠키 옵션 객체의 signed 값이 true여야 함.
 - 쿠키 확인 -> req.signedCookies 객체에서 확인
 - 쿠키 삭제 -> res.clearCookie(쿠키 이름, 쿠키 값, 쿠키 옵션 객체) // ver1.과 동일

🖥️Session🖥️

  • 서버 측에서 사용자 정보를 저장하고 관리하는 방식 = 웹 서버에 저장되는 쿠키!
  • 사용자가 웹 사이트에 접속할 때 서버는 고유한 세션 ID를 생성
  • 세션은 서버에서 관리되므로 쿠키보다 보안성이 높다!
더보기
// session.js

const express = require("express");
const session = require("express-session");
const app = express();
const PORT = 8080;

app.set("view engine", "ejs");

// session middleware 등록
app.use(
  session({
    secret: "secret", // 필수 값, .env에서 관리할 것
    resave: false,
    saveUninitialized: false,
    cookie: {
      httpOnly: true,
      maxAge: 10 * 60 * 1000, // 10분짜리 세션 쿠키
    },
  })
);
/*
 session({
    secret: 서명 값(필수 값) -> string
    resave: 세션에 수정사항이 생기지 않더라도 매 요청마다 세션을 다시 저장할지 -> boolean (false 권장)
    saveUninitialized: 세션에 저장할 내용이 없더라도 처음부터 세션을 생성할지 -> boolean (flase 권장)
    cookie:{} 세션 쿠키에 대한 설정 (cookie.js의 config 참고)
    secure: true일 때는 https에서만 세션을 주고 받는다.
    name: 세션 쿠키의 이름(sessionID값 저장하는 쿠키 이름, default: connect.sid)
  })

*/

app.get("/", (req, res) => {
  res.render("session");
});

// 세션 설정
app.get("/set", (req, res) => {
  // req.session.키 이름 = value (원하는 값)
  req.session.name = "potter";
  res.send("session 설정 완료");
});

// 세션 확인 (가져오기)
app.get("/get", (req, res) => {
  console.log(req.session);
  console.log(req.sessionID);
  res.send({ id: req.sessionID, name: req.session.name });
});

// 세션 삭제
app.get("/destroy", (req, res) => {
  console.log(res.session);
  req.session.destroy((err) => {
    if (err) throw err;

    res.send("세션 삭제 완료");
  });
});

app.listen(PORT, () => {
  console.log(`http://localhost:${PORT}`);
});

💡 주요 차이점

  1. 저장 위치: 쿠키는 클라이언트(브라우저)에, 세션은 서버에 저장
  2. 보안: 세션이 쿠키보다 더 안전
  3. 수명: 쿠키는 설정된 만료 기간까지 유지되고, 세션은 보통 브라우저를 닫을 때 종료