쿠키 vs localStorage vs sessionStorage: 클라이언트 저장소 선택
웹 애플리케이션을 구축할 때, 사용자의 테마 설정, 장바구니, 인증 토큰 등 클라이언트 측에 데이터를 저장해야 하는 경우가 많습니다. 세 가지 주요 옵션은 쿠키, localStorage, sessionStorage입니다. 각각 고유한 특성을 가지고 있어 다양한 시나리오에 적합합니다. 잘못 선택하면 보안 취약점, 성능 문제 또는 사용자 경험 저하로 이어질 수 있습니다.
이 글에서는 차이점을 분석하고 실용적인 지침을 제공하며, 다음 프로젝트에 어떤 저장 메커니즘을 사용할지 결정하는 데 도움을 드립니다.
빠른 비교
자세히 알아보기 전에 세 가지 저장 유형에 대한 개요를 살펴보세요:
| 기능 | 쿠키 | localStorage | sessionStorage |
|---|---|---|---|
| 용량 | 도메인당 ~4KB | 오리진당 ~5-10MB | 오리진당 ~5-10MB |
| 지속성 | 만료 기간 설정 가능 | 명시적으로 삭제할 때까지 | 탭/창 닫힐 때까지 |
| 서버로 전송 | 모든 HTTP 요청과 함께 자동 전송 | 아니요 | 아니요 |
| JavaScript 접근 가능 | 예 (HttpOnly가 아닌 경우) | 예 | 예 |
| 범위 | 도메인 및 경로 | 오리진 (프로토콜 + 도메인 + 포트) | 오리진 + 탭/창 |
| XSS 취약성 | 예 (HttpOnly가 아닌 경우) | 예 | 예 |
| CSRF 취약성 | 예 (인증에 사용 시) | 아니요 | 아니요 |
쿠키: 최초의 클라이언트 저장소
쿠키는 웹 초기부터 존재해 왔습니다. 브라우저가 저장하고 동일 도메인에 대한 모든 HTTP 요청과 함께 서버로 자동 전송하는 작은 데이터 조각(최대 ~4KB)입니다.
쿠키를 사용해야 할 때
- 인증 세션: 서버가 각 요청을 검증하는 데 필요한 세션 ID나 토큰을 저장합니다. XSS 및 CSRF 위험을 완화하려면
HttpOnly,Secure,SameSite플래그를 사용하세요. - 서버 측 개인화: 서버가 페이지를 렌더링하기 전에 사용자 설정(예: 언어, 테마)을 알아야 할 때.
- 추적 및 분석: 쿠키는 세션 간에 지속되고 구성에 따라 하위 도메인 간에 공유될 수 있습니다.
보안 고려 사항
쿠키는 자동으로 전송되므로 추가 보호 장치 없이 인증에 사용하면 CSRF에 취약합니다. 항상 SameSite 속성(Lax 또는 Strict)을 설정하고 CSRF 토큰 사용을 고려하세요. 민감한 데이터의 경우 HttpOnly를 사용하여 JavaScript 접근을 차단하고 XSS 영향을 줄이세요.
HTTP 응답에서 보안 쿠키를 설정하는 예:
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=3600
localStorage: 영구 키-값 저장소
localStorage는 브라우저를 닫아도 유지되는 간단한 키-값 저장소를 제공합니다. 데이터는 오리진(프로토콜 + 도메인 + 포트)별로 저장되며 서버로 자동 전송되지 않습니다. 페이지 새로고침과 브라우저 재시작 후에도 유지되어야 하는 비민감 데이터를 저장하는 데 이상적입니다.
localStorage를 사용해야 할 때
- 사용자 설정: 테마(다크/라이트), 글꼴 크기, 언어 또는 레이아웃 설정.
- 캐싱: API 응답이나 정적 데이터를 저장하여 네트워크 요청을 줄이고 오프라인 경험을 개선합니다.
- 클라이언트 측 상태: 장바구니 내용, 임시 양식 데이터 또는 기능 플래그.
보안 고려 사항
localStorage는 JavaScript로 접근할 수 있으므로 XSS 취약점이 있으면 저장된 모든 데이터가 노출될 수 있습니다. 강력한 XSS 보호 장치가 없는 한 비밀번호, 개인 식별 번호 또는 인증 토큰과 같은 민감한 정보를 저장하지 마세요. 토큰을 저장해야 한다면 HttpOnly 쿠키 접근 방식을 고려하세요.
localStorage 사용 예:
// 사용자 설정 저장
localStorage.setItem('theme', 'dark');
// 설정 검색
const theme = localStorage.getItem('theme');
// 항목 제거
localStorage.removeItem('theme');
sessionStorage: 탭별 저장소
sessionStorage는 localStorage와 유사하지만 수명이 더 짧습니다: 탭이나 창을 닫으면 데이터가 지워집니다. 단일 탭으로 범위가 제한되므로 동일한 오리진이라도 탭이나 창 간에 데이터가 공유되지 않습니다.
sessionStorage를 사용해야 할 때
- 다단계 양식: 사용자가 단계를 진행하는 동안 양식 데이터를 임시로 저장하고 완료 후에는 유지하지 않습니다.
- 단일 탭 상태: 임시 인증 상태나 일회용 토큰과 같이 탭 간에 유출되지 않아야 하는 데이터.
- 민감한 작업: 사용자가 탭을 닫으면 데이터가 자동으로 지워져 노출을 줄이고 싶을 때.
보안 고려 사항
localStorage와 마찬가지로 sessionStorage는 XSS에 취약합니다. 그러나 수명이 제한적이고 탭별 범위이므로 공격자의 기회 창이 줄어듭니다. 그래도 매우 민감한 데이터는 저장하지 않는 것이 좋습니다.
sessionStorage 사용 예:
// 양식 데이터 저장
sessionStorage.setItem('formStep1', JSON.stringify({name: 'John'}));
// 양식 데이터 검색
const step1 = JSON.parse(sessionStorage.getItem('formStep1'));
선택 방법: 의사 결정 가이드
다음 순서 목록을 사용하여 결정을 안내하세요:
- 서버가 모든 요청에서 데이터를 읽어야 하나요? 그렇다면 쿠키를 사용하세요. 예: 세션 ID.
- 데이터가 브라우저 세션 간에 유지되어야 하나요? 그렇다면 localStorage를 사용하세요. 예: 사용자 설정.
- 데이터가 단일 탭으로 제한되어야 하나요? 그렇다면 sessionStorage를 사용하세요. 예: 다단계 양식 데이터.
- 데이터가 민감한가요? localStorage나 sessionStorage에 저장하지 마세요. 토큰에는 HttpOnly 쿠키를 사용하고 비밀번호는 절대 저장하지 마세요.
- 데이터가 큰가요? 쿠키는 ~4KB로 제한되지만 localStorage와 sessionStorage는 훨씬 더 많은 용량을 제공합니다.
보안 모범 사례
- 항상 입력을 검증하고 정제하세요 — XSS를 방지하여 모든 클라이언트 측 저장소를 보호합니다.
- 인증 토큰에는 HttpOnly, Secure, SameSite 쿠키를 사용하세요 — XSS와 CSRF를 완화합니다.
- 민감한 데이터를 localStorage나 sessionStorage에 저장하지 마세요. 불가피한 경우 암호화하고 짧은 만료 시간을 사용하세요.
- 콘텐츠 보안 정책(CSP)을 구현하세요 — XSS 위험을 줄입니다.
- 오래된 데이터를 정기적으로 지우세요 — 저장 한도에 도달하는 것을 방지하고 노출을 줄입니다.
FAQ
인증 토큰에 localStorage를 사용할 수 있나요?
localStorage는 JavaScript로 접근할 수 있어 토큰이 XSS에 취약해지므로 권장하지 않습니다. Secure 및 SameSite 플래그가 있는 HttpOnly 쿠키를 선호하세요.
탭을 복제하면 sessionStorage는 어떻게 되나요?
탭을 복제하면 새 탭은 복제 시점의 원본 탭 sessionStorage 복사본을 갖습니다. 그 이후에는 독립적입니다.
쿠키는 모든 요청에서 서버로 전송되나요?
예, 현재 도메인의 쿠키는 모든 HTTP 요청에 자동으로 포함되므로 너무 많은 데이터를 저장하면 성능에 영향을 줄 수 있습니다. 절약해서 사용하세요.
저장하는 JSON 데이터를 빠르게 포맷하거나 검증해야 하나요? 클라이언트 저장소에 저장하기 전에 JSON 페이로드를 보기 좋게 만들고 디버깅하려면 JSON Formatter를 사용해 보세요.