로컬스토리지, 세션스토리지, 세션, 쿠키의 이해
2024. 2. 15. 16:54

로컬스토리지, 세션스토리지, 세션, 쿠키 모두 데이터 저장소로 사용되는 것에 있어서 공통점을 갖기 때문에 함께 언급되는 경우가 많이 생긴다. 하지만 브라우저에 저장되냐 서버에 저장되냐 또는 임시적으로 저장되냐 영구히 저장되냐 등과 같은 특성이 서로 다르기 때문에 사용하는 용도가 조금씩 다르고 이에 대한 이해가 있어야 올바르게 사용이 가능하다.

 

참고로 본인은 세션(Session)이라는 용어가 쿠키 같이 특정 하나의 도구(?)의 명칭인 줄 알았으나 컨택스트(Context) 같이 광범위한 의미로 여러 곳에 쓰이는 용어임을 깨달았다. 특히, 컴퓨터 분야에서는 네트워크를 통해 정보를 교환함에 있어서 서로 연결되어 있다 또는 정보를 주고받는 상태이다와 같은 의미로 해석이 가능하다. 

 

제목에 쓰인 4가지 데이터 저장도구 모두 로그인 정보 데이터를 담는 도구로 활용될 수 있으며, 이러한 곳의 데이터가 손실되거나 삭제 됐을 때 로그인 상태를 증명할 수 없게 되고 세션이 끊겼다고 표현할 수 있는 것이다. 

 

 

로컬스토리지(LocalStorage)와 세션스토리지(SessionStorage)

브라우저 내에 키-값 쌍을 저장할 수 있는 웹 스토리지 객체(web storage object)웹 브라우저에 저장된다. 백엔드에서 직접적으로 컨트롤이 불가능하며 클라이언트 단에서만 컨트롤(생성, 삭제, 수정, 읽기)이 가능하다. 저장용량은 브라우저마다 다른데 보통 5~10MB로 4KB인 쿠키에 비해 큰 용량을 할당할 수 있어 상대적으로 큰 데이터를 저장하기 용이하다. HTTP통신 시 함께 전달되지 않기 때문에 전달하고 싶은 데이터는 클라이언트에서 해더 같은 곳에 넣어 함께 보낼 수 있다.

 

  1. 로컬스토리지
    • 오리진이 같은 경우 모든 탭과 창에서 데이터 공유
    • 로컬스토리지가 갱신 될 경우 (같은 도메인) 모든 창에서 window.onstorage을 통해 이벤트 감지가 가능하여 메시지 교환이나 데이터 갱신이 가능함
    • 브라우저나 OS가 재시작하더라도 데이터 보존
  2. 세션스토리지
    • 현재 떠 있는 탭 내에서만 데이터 유지
    • 같은 페이지라도 다른 탭에 있으면 데이터 공유X
    • 같은 탭 내에 iframe에서 데이터 공유
    • 탭을 닫으면 데이터가 사라지나 새로고침은 유지됨

 

세션(Session)

클라이언트와 서버 간의 상태를 유지하기 위한 메커니즘으로 서버 측에 데이터가 저장되어 관리된다. Express를 예를 들면 세션기능을 통해 연결된 사용자 정보를 세션(백단, 서버)에 저장하고 해당 sessionID를 쿠키에 저장한다. 이렇게 되면 다른 요청이 들어올 때 쿠키에 담긴 sessionID를 통해 서버에 저장된 사용자 정보를 조회하여 활용할 수 있다.

 

const express = require('express');
const session = require('express-session');
const cookieParser = require('cookie-parser');

const app = express();

// 쿠키 파서 미들웨어 사용
app.use(cookieParser());

// 세션 설정
app.use(session({
  secret: 'my-secret-key', // 세션 암호화를 위한 키
  resave: false,
  saveUninitialized: true,
  cookie: { 
      httpOnly: true, // HttpOnly 속성 활성화
      maxAge: 60 * 60 * 1000 // 1시간 동안 유효한 세션 쿠키 설정
  }
}));

// 최초 요청에서 세션을 생성하고 세션 식별자를 클라이언트에게 전달합니다.
app.get('/', (req, res) => {
  // 세션에 사용자 정보를 저장할 수 있습니다.
  req.session.user = { id: 123, username: 'example' };

  // 세션 쿠키를 클라이언트에게 전송합니다.
  res.cookie('sessionID', req.sessionID, { httpOnly: true });
  res.send('Session created');
});

// 이후의 모든 요청에서 세션을 사용합니다.
app.get('/user', (req, res) => {
  // 세션에서 사용자 정보를 읽어옵니다.
  const user = req.session.user;
  
  if (user) {
    res.send('User: ' + JSON.stringify(user));
  } else {
    res.send('User not found');
  }
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

 

 

쿠키(Cookies)

쿠키는 (특별한 설정이 없으면) HTTP 통신 시 헤더에 함께 포함되어 항상 전달되기 때문에 최대 4KB 정도의 작은 최대 용량을 갖는 놈으로 아래와 같은 특징을 갖는다.

  • 서버와 클라이언트 모두에서 세팅이 가능하지만 주로 백단에서 관리됨
  • httpOnly 설정을 통해 백단에서 세팅한 쿠키값을 클라이언트단에서 조회하거나 수정할 수 없도록 설정할 수 있음
  • 그 반대인 클라이언트에서 설정한 쿠키를 백단에서 컨트롤하지 못하게 하는 방법은 없는 것으로 보임...
  • 쿠키가 업데이트되면 같은 도메인의 모든 탭 모든 창에서 업데이트됨
  • 최대 2년 정도의 만료기간을 설정할 수 있으며, 따로 만료시간 설정이 없다면 창이 닫힐 때까지만 유지되는 세션 쿠키가 됨
  • 해당 도메인 또는 Path에서만 쿠키가 담겨서 사용될 수 있도록 설정이 가능
  • Secure를 통해 HTTP가 아닌 HTTPS인 경우만 쿠키를 사용하게 설정 가능
  • SameSite를 통해 CORS정책 설정 가능
    • None : 요청이 다른 오리진에서 기인해도 쿠키 포함
    • Lax : 기본값으로 GET 같은 안전한 메소드의 경우에만 쿠키를 포함, POST 같이 서버의 상태를 변화시키는 메소드에는 포함X
    • Strict : 어떠한 경우에도 다른 오리진의 요청에는 쿠키 포함X

 

결론

로컬스토리지, 세션스토리지, 쿠키는 브라우저에 저장되며 세션은 서버에 저장된다. 또한 각자 데이터의 유효기간, 휘발성 등의 특성이 다르기 때문에 각각의 특성에 맞게 사용하는 지혜가 필요하다. 예를 들어 무조건 로그인되어야 사용가능한 서비스라면 로그인 정보를 쿠키에 담아야 할 테지만(거의 대부분의 요청에서 사용자 증명이 필요하니) 로그인 정보 없이 처리될 요청이 많은 사이트라면 로컬스토리지 같은 곳에 로그인 정보를 담아 http통신 시 선택적으로 데이터를 전달하여 서버의 부하를 낮출 수 있을 것이다.

 

 

참고문헌