웹 개발에서의 쿠키와 세션 이해하기

민정이등장·2024년 10월 24일
0

1. 웹 브라우저의 쿠키와 웹 서버 관리


1-1. 웹 브라우저의 쿠키 이해

  • 웹 브라우저에서의 쿠키는 키와 값의 형태로 저장되며, 이는 요청 정보를 담아준다.
  • 쿠키는 도메인, 경로, 만료일 등의 정보를 포함하며, 이 정보는 요청을 받았을 때 서버로 전달된다.
  • 해당 도메인에 이미 저장된 쿠키는 브라우저가 닫혀도 다시 나타나며, 만료된 쿠키는 삭제된다.
  • 쿠키는 만료 기간이 지나면 만료된 쿠키는 삭제되고, 그 도메인에 대해 새로운 쿠키를 생성한다.

1-2. 웹 서버의 쿠키 저장 및 전송

  • 웹 서버는 쿠키 파서를 통해 쿠키를 생성하고 저장한다.
  • 웹 브라우저 요청이 들어올 때, 서버에서 쿠키를 생성하여 응답에 함께 전송한다.
  • 클라이언트 측에서 쿠키를 이미 가지고 있다면, 이전에 만들어 둔 쿠키를 사용하여 처리한다.
  • 웹 서버는 이전 요청과 동일한 요청이 다시 들어올 경우, 이전에 만들어 놓았던 쿠키를 사용한다.

1-3. 웹 서버의 쿠키 관리 및 사용

  • 웹 서버는 쿠키 파서를 통해 쿠키를 생성 및 저장한다.
  • 쿠키의 만료 기간은 웹 서버에서 설정 가능하며, 웹 브라우저가 닫혀도 해당 도메인에 쿠키가 남아있다.
  • 웹 서버는 쿠키의 접근 가능성을 보완하여, 웹 브라우저를 통해 접속한 쿠키만 접근 가능하도록 설정한다.
  • 쿠키의 수명은 밀리초로 설정될 수 있으며, 만료일을 특정 날짜로 설정할 수도 있다. 웹 브라우저에서 전송된 도메인을 지정 가능하다.

🔍 Cookie의 동작방식


  1. 클라이언트가 페이지를 요청한다.
  2. 서버에서 쿠키를 생성한다.
  3. http 헤더에 쿠키를 포함시켜 응답한다.
  4. 브라우저가 종료되어도 쿠키 만료 기간이 있다면 클라이언트에서 보관하고 있다.
  5. 같은 요청을 할 경우 http 헤더에 쿠키를 함께 보낸다.
  6. 서버에서 쿠키를 읽어 이전 상태 정보를 변경 할 필요가 있을 때 쿠키를 업데이트하여 변경된 쿠키를 http 헤더에 포함시켜 응답한다.
EX ) 웹사이트 로그인 페이지의 자동로그인, 알람창의 오늘그만보기 등


먼저 npm install cookie-parser 명령어를 설치한다.

const cookieParser = require("cookie-parser");
app.use(cookieParser()); // 일반쿠키
app.use(cookieParser("SecretKey")); // SecretKey는 임의로 설정할 수 있는 비밀 키 (밑에서 설명)
.
.
.
res.cookie("쿠키이름", "쿠키값", "옵션객체")

2. 웹 브라우저와 웹 서버의 쿠키 설정 및 암호화 방법


2-1. 웹 브라우저와 웹 서버의 기본 설정

  • 웹 브라우저와 웹 서버는 다양한 도메인을 통해 통신한다. (구글이나 네이버 등)
  • 웹 브라우저와 웹 서버가 HTTPS로 송신하는 경우에만 쿠키를 서버에 전송한다.
  • 쿠키는 기본적으로 고객이 요청한 키를 포함하며, 추가로 키가 포함된 쿠키를 생성할 수 있다.
  • 쿠키 설정 후 쿠키의 기본 정보를 확인하거나, 쿠키가 약화된 경우 암호화를 통해 정보를 복원할 수 있다.

2-2. 웹 브라우저와 웹 서버의 쿠키 제거

  • 쿠키를 제거하기 위해서는 해당 쿠키를 삭제해야 한다.
  • 제거를 위해서는 액세스 제어로 쿠키를 검증한 후, 쿠키 삭제 요청을 보낸다.
  • 제거된 쿠키는 서버 내의 쿠키 테이블에서 삭제된다.
  • 삭제되지 않은 쿠키는 다른 쿠키에 저장되어 관리된다.

2-3. 웹 브라우저와 웹 서버의 쿠키 암호화

  • 쿠키를 암호화하기 위해서는 쿠키에 Signed 속성을 추가해야 한다.
  • 추가된 Signed 쿠키는 키와 벨류만 포함하며, 암호화된 쿠키를 생성할 수 있다.
  • 암호화된 쿠키는 서명된 쿠키를 통해 확인이 가능하며, 서버에서 생성된 쿠키임을 인증한다.
  • 비밀 키를 통해 암호화된 쿠키는 비밀 키를 통해 진위를 판별하여 위조를 방지한다.


3. 웹 상황에서의 쿠키와 세션의 이해


3-1. 웹 상황에서의 쿠키 설정과 사용

  • 웹 상황에서 쿠키는 사용자의 브라우저 정보를 저장하는 수단이다.
  • 쿠키는 클라이언트 측에 저장되며, 보안 상황에서 중요한 정보를 담아둔다.
  • 세션은 사용자의 요청 시 서버에서 발급하는 정보 저장 수단이다.
  • 세션은 서버 측에 저장되며, 사용자 정보를 기반으로 요청을 처리하거나 다른 형태의 데이터를 반환하는 역할을 한다.

3-2. 세션의 개념과 동작

  • 세션은 서버에 저장되며, 특정 사용자를 식별하는 데 사용된다.
  • 클라이언트에 발급된 세션 ID는 서버에서 세션을 식별하는 데 사용된다.
  • 이 세션 아이디를 통해 클라이언트의 정보를 서버에 가져올 수 있다.
  • 세션은 보안 측면에서 중요하며, 세션 하이재킹 등의 공격을 방지하기 위해 주의해야 한다.

    📖 하이재킹 방지 쿠키속성 설명


    httpOnly : 웹 서버를 통해서만 쿠키에 접근 가능하다.
    maxAge : 쿠키의 수명을 설정하여, 일정 시간이 지나면 쿠키가 자동으로 삭제되도록 한다. (단위는 밀리초)
    expires : 만료 날짜를 GMT 시간대로 설정한다.
    path : 쿠키가 활성화될 경로를 설정하여, 특정 디렉토리와 하위 디렉토리에서만 쿠키가 사용되도록 한다.
    {웹 브라우저는 해당하는 쿠키만 웹 서버에 전송 ( 기본값 : / )}
    domain : 쿠키가 전송될 도메인을 특정한다. ( 기본값 : 현재 도메인 )
    secure : 웹 브라우저와 웹 서버가 https로 통신하는 경우에만 쿠키를 전송한다.
    signed : 쿠키의 암호화 결정하여 변조된 쿠키가 서버로 전송되는 것을 방지한다.

3-3. 세션 설정 방법과 세션 관련 옵션

  • 세션 설정은 쿠키와 달리 보안에 중점을 두어야 한다.
  • 세션 설정에서는 시크릿 키를 활용하여 정보를 저장하거나 다시 저장하는 방법을 설정할 수 있다.
  • 세션 설정에는 정보를 저장하거나 초기화하는 방법을 포함하여, 세션의 유지 및 초기화 옵션을 설정할 수 있다.
  • 세션 설정을 통해 사용자의 요청에 따라 정보를 저장하거나 초기화할 수 있다.

4. 클라우드 케어를 통한 데이터 관리

4-1. 클라우드 케어를 통한 데이터 관리 개요

  • 클라우드 케어는 데이터 관리의 편리성을 증대시키는 수단이다.
  • 세션 액션 설정을 통해 데이터의 변환을 유연하게 처리할 수 있다.
  • 메소드를 활용하여 데이터의 변환 상태를 실시간으로 확인할 수 있다. ( EX, getDataStatus 메소드를 활용하여 데이터의 변환 상태를 실시간으로 확인할 수 있다. )
  • 콘솔을 통해 현재 세션의 ID 값을 알 수 있으며, 이를 통해 원하는 데이터 변환을 수행할 수 있다.
  • 삭제 메소드를 활용하여 데이터 변환을 완료하고, 콜백 함수를 통해 성공 여부를 판단할 수 있다.

4-2. 클라우드 케어를 통한 데이터 관리 심층 분석

  • 클라우드 케어는 데이터 관리의 보안성과 편리성을 동시에 증진시킬 수 있는 방법이다.
  • 서버와 클라이언트 모두에서 데이터 변환의 유연성을 확보할 수 있다.
  • 쿠키(로컬 클라이언트 정보)와 세션(서버 세션 정보)를 통해 데이터 변환 상태를 실시간으로 확인할 수 있다.
  • 클라이언트 측에서 데이터 변환 상태를 압도적으로 확인할 수 있어 보안성이 향상된다.
  • 서버 측에서 데이터 변환을 보안적으로 처리함으로써 악의적인 행위를 예방하는 데 효과적이다.

4-3. 클라우드 케어를 통한 데이터 관리 구현

  • 세션 액션 설정을 통해 데이터 변환을 유연하게 처리할 수 있다.
  • 메소드를 통해 현재 세션의 ID 값을 알 수 있어, 원하는 데이터 변환을 실시간으로 확인할 수 있다.
  • 콘솔을 통해 현재 세션의 상태와 변환 상태를 실시간으로 확인할 수 있다.
  • 삭제 메소드를 활용하여 데이터 변환을 완료하고, 콜백 함수를 통해 성공 여부를 판단할 수 있다. ( EX, 사용자가 요청한 특정 세션 데이터를 삭제하기 위해 deleteSessionData 메소드를 활용하고, 성공 여부를 판단하기 위해 콜백 함수를 사용할 수 있다. )
  • 클라우드 케어를 통해 데이터 관리의 편리성과 보안성을 동시에 증진시킬 수 있다.

🔍 Session의 동작방식


  1. 클라이언트가 서버에 접속시 세션 ID를 발급받는다.
  2. 클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 가지고 있는다.
  3. 클라이언트는 서버애 요청할 때, 이 쿠키의 세션 ID를 서버에 전달해서 사용한다.
  4. 서버는 세션 ID를 전달받아서 별다른 작업없이 세션 ID로 세션에 있는 클라이언트 정보를 가져온다.
  5. 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답한다.

🔍 Session 사용방법


먼저 npm install express-session 명령어를 설치한다.

const session = require("express-session");
app.use(session("옵션객체"));
.
.
.
// req.session.key = value
req.session.id = req.body.id;


  • 전체적인 역할과 동작 원리: 쿠키와 세션은 사용자 정보를 저장하는 방식이며, 세션은 서버 측에서 관리되는 쿠키라고 볼 수 있다.
  • 쿠키:
    • 저장 위치: 클라이언트의 브라우저에 저장.
    • 유효 기간: 만료 기간을 설정할 수 있음.
    • 속도: 서버 요청 없이 즉시 접근 가능해 빠름.
    • 보안: 민감한 정보를 저장하는 데는 적합하지 않음 (XSS 공격에 취약).
  • 세션:
    • 저장 위치: 서버에 저장.
    • 유효 기간: 서버에서 세션 만료 시간을 설정.
    • 속도: 서버 요청 시마다 세션 ID를 확인해야 하므로 약간 느릴 수 있음.
    • 보안: 서버에서 관리되므로 보안성이 더 높고, 민감한 정보 저장에 적합.

views/cookie.ejs 파일

<h1>Cookie</h1>

<a href="/setCookie">쿠키 설정하기</a>
<a href="/getCookie">쿠키 확인하기</a>
<a href="/clearCookie">쿠키 제거하기</a>
views/cookie.js 파일

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

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

// cookie-parser

// 일반 쿠키
// app.use(cookieParser());

// 암호화 쿠키
app.use(cookieParser("mySecretKey"));
// secretKey : 비밀키
// - 서명된 쿠키가 있는 경우, 제공한 비밀키를 가지고 해당 쿠키가 내 서버가 만든 쿠키임을 인증 가능
// - 쿠키는 클라이언트에서 위조가 쉬우므로 비밀키를 통해 만든 서명을 쿠키 값 뒤에 붙임
// - 서명된 쿠키는 req.signedCookies 객체에 들어있음

// cookie 옵션 객체
const cookieConfig = {
  // httpOnly: 웹 서버를 통해서만 쿠키에 접근 가능
  // maxAge: 쿠키의 수명, 단위는 밀리초
  // expires: 만료 날짜를 GMT 시간대로 설정
  // path: 해당 디렉토리와 하위 디렉토리에서만 경로가 활성화되고
  //       웹 브라우저는 해당하는 쿠키만 웹 서버에 전송 (기본값: /)
  // domain: 쿠키가 전송될 도메인을 특정 가능 (기본값: 현재 도메인)
  // secure: 웹 브라우저와 웹 서버가 https로 통신하는 경우에만 쿠키를 서버에 전송
  // signed: 쿠키의 암호화 결정 (res.signedCookies 객체에 들어있음)
  httpOnly: true,
  maxAge: 60 * 1000, // 60초
  signed: true, // 암호화쿠키
};

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

// 쿠키 설정
app.get("/setCookie", (req, res) => {
  // res.cookie(쿠키 이름, 쿠키 값, 쿠키 옵션)
  res.cookie("myCookie", "myValue", cookieConfig);
  res.send("set cookie!");
});

// 쿠키 확인
app.get("/getCookie", (req, res) => {
  // res.send(req.cookies); // 일반 쿠키
  res.send(req.signedCookies); // 암호화 쿠키
});

// 쿠키 삭제
app.get("/clearCookie", (req, res) => {
  // res.clearCookie(키, 값, 옵션)
  res.clearCookie("myCookie", "myValue", cookieConfig);
  res.send("clear cookie!");
});

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

Session 예시

views/session.ejs 파일

<h1>Session</h1>

<a href="/set">세션 설정하기</a>
<a href="/get">세션 확인하기</a>
<a href="/destroy">세션 제거하기</a>
views/session.js 파일

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

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

// session 옵션 객체
const sessionConfig = {
  // secure: 값을 true로 하면 https에서만 세션을 주고 받음
  // secret: 안전하게 쿠키를 전송하기 위한 쿠키 서명 값 (세션을 발급할 때 사용되는 키)
  // resave: 세션에 수정사항이 생기지 않더라도, 매 요청마다 세션을 다시 저장할 것인지,
  //         세션을 항상 저장할 것인지 지정하는 값 (false 권장)
  // saveUninitialized: 세션에 저장할 내역이 없더라도 처음부터 세션을 생성할지 설정
  // httpOnly: 웹 서버를 통해서만 쿠키에 접근 가능
  // maxAge: 쿠키의 수명, 단위는 밀리초
  // => cookie 객체에 넣어서 정의

  secret: "mySessionSecret",
  resave: false,
  saveUninitialized: true,
  cookie: {
    httpOnly: true,
    maxAge: 60 * 1000, // 60초
  },
};

app.use(session(sessionConfig));

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

// 설정
app.get("/set", (req, res) => {
  // req.session.키 = 값
  req.session.name = "홍길동";
  res.send("set session!");
});

// 확인
app.get("/get", (req, res) => {
  // req.session.키 => 값 출력
  console.log(req.session.name);
  console.log(req.sessionID); // 현재 세션 아이디
  console.log(req.session);
  res.send({ id: req.sessionID, name: req.session.name });
});

// 삭제
app.get("/destroy", (req, res) => {
  req.session.destroy((err) => {
    if (err) {
      console.log(err);
      res.send("fail");
    }
    res.redirect("/get");
  });
});

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

0개의 댓글