흰 스타렉스에서 내가 내리지

쿠키와 세션 사용해보기 본문

Node.js

쿠키와 세션 사용해보기

주씨. 2022. 6. 28. 21:54
728x90

Header에 내용추가하기, Header를 통해서 쿠키 설정하기 

exports.main = function (req, res, next) {
  res.setHeader("Domi", "Thiem");	// 헤더 설정
  res.setHeader("Set-Cookie", "mycookie=test");	// 쿠키를 생성하는 명령어
  res.cookie("hana", "card");	// 쿠키 생성
  res.clearCookie("hana");	// 쿠키 제거
  res.render("home");
};

 


아주 간단한 로그인 로직 -  만료시간

const fs = require("fs");

exports.main = function (req, res, next) {
  res.setHeader("Domi", "Thiem");
  res.setHeader("Set-Cookie", "mycookie=test");
  res.render("home");
};

exports.cookieTest = function (req, res, next) {
  const cookies = parseCookies(req.headers.cookie);

  if (!cookies.name) {
    const expires = new Date();
    expires.setMinutes(expires.getMinutes() + 5);
    res.setHeader("Location", "/");
    res.setHeader(
      "Set-Cookie",
      `name=${encodeURIComponent(
        "joos"
      )}; Expires=${expires.toGMTString()}; HttpOnly; Path=/`
    );
    return res.render("home");
  } else if (cookies.name) {
    // name이라는 쿠키가 있는 경우
    res.setHeader("Content-Type", "text/plain; charset=utf-8");
    return res.json({ message: `${cookies.name}님 안녕하세요` });
  }
};

const parseCookies = (cookie = "") => {
  return cookie
    .split(";")
    .map((v) => v.split("="))
    .reduce((acc, [k, v]) => {
      acc[k.trim()] = decodeURIComponent(v);
      return acc;
    }, {});
};

처음 /cookie-test 로 접속을 하면, cookie에는 name 이 없기 때문에 if 문 실행. 

쿠키가 잘 저장이 되었다.

 

이제 다시 접속을 하면, name이라는 쿠키가 있기 때문에 else if 문 실행. 

안녕하세요가 화면에 뜨게 된다. 

 

만료 기간을 5분으로 했기때문에, 5분뒤에 새로고침해보면, 쿠키가 사라져 있는걸 볼 수 있다. 

 

 


쿠키의 각종 옵션

쿠키에는 들어가면 안 되는 글자들이 있는데, 대표적으로 한글과 줄바꿈이 있다. 

한글은 encodeURIComponent로 감싸서 넣는다. 

 

쿠키명=쿠키값 : 기본적인 쿠키의 값이다. mycookie=test 같이 설정한다. 

Expires=날짜 : 만료기한. 이 기한이 지나면 쿠키가 제거된다. 기본값은 클라이언트가 종료될 때 까지이다.

Max-age=초 : Expires와 비슷하지만 날짜 대신 초를 입력할 수 있다. 해당 초가 지나면 쿠키가 제거된다. Expires보다 우선한다.

Domain=도메인명 : 쿠키가 전송될 도메인을 특정할 수 있다. 기본값은 현재 도메인이다.

Path=URL : 쿠키가 전송될 URL을 특정할 수 있다. 기본값은 '/'이고, 이 경우 모든 URL에서 쿠키를 전송할 수 있다. 

Secure : HTTPS일 경우에만 쿠키가 전송된다.

HttpOnly : 설정 시 자바스크립트에서 쿠키에 접근할 수 없다. 쿠키 조작을 방지하기 위해 설정하는 것이 좋다. 

 

 


세션쿠키

const session = {};

exports.sessionTest = function (req, res, next) {
  const cookies = parseCookies(req.headers.cookie);
  if (!cookies.session) {
    const name = "joos";

    const expires = new Date();
    expires.setMinutes(expires.getMinutes() + 5);

    const uniqueInt = Date.now();
    session[uniqueInt] = {
      name,
      expires,
    };
    res.setHeader(
      "Set-cookie",
      `session=${uniqueInt}; Expires=${expires.toGMTString()}; HttpOnly; Path=/`
    );
    return res.render("home");
  }
  // 세션 쿠키가 존재하고, 만료 기간이 지나지 않았다면
  else if (cookies.session && session[cookies.session]?.expires > new Date()) {
    res.setHeader("Content-Type", "text/plain;charset=utf-8");
    return res.json({
      message: `${session[cookies.session].name}님 안녕하세요.`,
    });
  } else {
    // 세션쿠키가 클라이언트에 저장이 되어있는데 서버를 재시작하여 서버상 session에 아무것도 들어있지 않을 때
    return res.render("home");
  }
};

 

세션 ID를 쿠키로 클라이언트에 전송해 주고, 클라이언트는 이 세션 ID와 함께 서버에 요청을 보낸다.

서버에서 저장된 딕셔너리 형태로 저장된 세션ID와 사용자에 대한 정보를 이용하여 사용자를 특정한다. 

 

마찬가지로 만료기간이 지나면 없어진다. 

 

 

 

서버에 사용자 정보를 저장하고 클라이언트와는 세션 아이디로만 소통한다. 

세션아이디는 꼭 쿠키를 사용해서 주고받지 않아도 된다. 하지만 많은 웹 사이트가 쿠키를 사용한다. 

세션을 위해 사용하는 쿠키를 세션 쿠키라고 부른다.

 

실제 배포용 서버에서는 세션을 위와 같이 변수에 저장하지 않는다.

서버가 멈추거나 재시작되면 메모리에 저장된 변수가 초기화되기 떄문이다. 

또한, 서버의 메모리가 부족하면 세션을 저장하지 못하는 문제도 생긴다. 

그래서 보통은 레디스(Redis)나 멤캐시드(Memcached) 같은 데이터베이스에 넣어둔다. 

 

위와 같은 방식으로 세션 아이디 값이 공개되어 있어 유출되면 다른사람이 사용할 수 있다.

따라서 절대로 위의 코드를 실제 서비스에 사용해서는 안된다. 

 

 


cookie-parser

cookie-parser는 요청에 동봉된 쿠키를 해석해 req.cookies 객체로 만든다. 

위에서 만든 parseCookies 함수와 기능이 비슷하다.

const cookieParser = require("cookie-parser");

app.use(cookieParser("KUH"));
exports.createCookie = function (req, res, next) {
  res.cookie("NIVEA", "STRAWBERRY", {
    expires: new Date(Date.now() + 900000),
    httpOnly: true,
    secure: true,
    signed: true, // 서명된 쿠키
  });
  return res.render("home");
};

exports.removeCookie = function (req, res, next) {
  res.clearCookie("NIVEA", "STRAWBERRY");
  return res.render("home");
};

\\

signed 라는 옵션을 통해 쿠키 뒤에 서명을 붙일 수 있다. 

내 서버가 만든 쿠키라는 것을 검증할 수 있으므로 대부분의 경우 서명 옵션을 켜두는 것이 좋다.

 

콘솔 로그를 찍어보면, 

 

cookieParser 키를 바꿧을 때 :

못읽는다.

 

 


express-session

const session = require("express-session");

app.use(
  session({
    resave: false, // 요청이 올 때 세션에 수정사항이 생기지 않더라도 세션을 다시 저장할지
    saveUninitialized: false, // 세션에 저장할 내역이 없더라도 처음부터 세션을 생성할지
    secret: "KUH", // 쿠키 서명
    cookie: {
      httpOnly: true,
      secure: false, // false 이면 https가 아닌 환경에서도 사용할 수 있음
    },
    name: "session-cookie", //  세션 쿠키의 이름, default 값은 connect.sid
  })
);

 

'Node.js' 카테고리의 다른 글

로그를 남겨주는 winston 패키지  (0) 2022.06.13
서버가 꺼졌을 때 자동으로 다시 켜주는 pm2 패키지  (0) 2022.06.13
배포  (0) 2022.06.12
nodeJS 프로젝트 준비  (0) 2022.06.12
미들웨어 속의 미들웨어??  (0) 2022.05.28