쿠키부터 세션, JWT까지
웹 인증 이야기를 하다 보면 항상 같은 단어들이 등장합니다.
- 쿠키
- 세션
- JWT
보통은 이렇게 정리됩니다.
"옛날엔 세션, 요즘은 JWT"
하지만 실무에서 이 문장은 절반만 맞고 절반은 틀린 말입니다.
이 글에서는
- 이 기술들이 어떤 문제를 해결하려고 등장했는지
- 왜 지금까지도 함께 쓰이고 있는지
- 프론트엔드 개발자가 어디까지 이해하고 판단해야 하는지
를 중심으로 정리해보려 합니다.
모든 문제의 시작: HTTP는 상태를 기억하지 않는다
HTTP의 가장 중요한 특징은 Stateless입니다.
요청 A와 요청 B 사이에는 아무런 연결도 없다.
이 말은 곧,
- 로그인 요청
- 게시글 조회 요청
이 두 요청이 같은 사용자의 것인지 서버는 알 수 없다는 뜻입니다.
결국 웹 인증의 본질은 "이 요청을 보낸 사람이 누구인지 어떻게 증명할 것인가" 입니다.
이 질문에 대한 서로 다른 답이
- 쿠키
- 세션
- JWT
로 발전해왔습니다.
쿠키: 가장 단순한 상태 유지 장치
쿠키의 발상
가장 처음 나온 아이디어는 단순합니다.
"브라우저가 값을 기억하고 있다가, 요청할 때마다 같이 보내면 되지 않을까?"
이게 바로 쿠키입니다.
Set-Cookie: userId=123
이후 같은 도메인으로 요청하면 브라우저는 자동으로 쿠키를 포함합니다.
Cookie: userId=123
쿠키의 한계는 명확했다
쿠키는 너무 자유로웠습니다.
- 클라이언트가 마음대로 수정 가능
- 민감 정보 저장 불가
- 매 요청마다 전송됨
즉,
"인증 정보의 진실성을 보장할 수 없다"
라는 치명적인 문제가 있었습니다.
그래서 자연스럽게 이런 방향으로 생각이 바뀝니다.
"중요한 정보는 서버에 두자"
세션: 상태를 서버로 되돌리다
세션의 핵심 아이디어
세션은 이렇게 역할을 나눕니다.
- 브라우저: 식별자만 보관
- 서버: 실제 사용자 정보 보관
브라우저 ── sessionId ──▶ 서버
서버 ── sessionId로 사용자 조회
이 구조 덕분에
- 쿠키 조작 위험 감소
- 서버에서 강제 로그아웃 가능
이라는 장점을 얻습니다.
하지만 세션은 서버를 기억하게 만든다
문제는 여기서부터입니다.
서버가
- 세션을 저장하고
- 요청마다 조회해야 한다는 것
즉, 서버가 상태를 갖게 됩니다.
이 구조는
- 서버가 1대일 때는 문제없지만
- 서버가 여러 대가 되는 순간
갑자기 복잡해집니다.
요청이 어떤 서버로 가느냐에 따라
세션이 있기도, 없기도 하다.
이 문제를 해결하기 위해
- Sticky Session
- Redis 같은 외부 세션 저장소
가 등장하지만, 구조는 점점 무거워집니다.
JWT: 상태를 없애고 싶다는 욕망
JWT가 등장한 배경
시대가 바뀌면서 서버 환경도 바뀌었습니다.
- 서버 다중화
- MSA
- 모바일 / 외부 API
이 환경에서 세션은 너무 많은 전제를 요구했습니다.
"서버가 아무것도 기억하지 않으면 안 될까?"
이 질문에 대한 답이 JWT입니다.
JWT는 무엇을 해결했나
JWT의 핵심은 단순합니다.
- 사용자 정보를 토큰에 담고
- 서버는 서명만 검증한다
요청 ── JWT ──▶ 서버
서명 검증 OK → 사용자 신뢰
서버는 더 이상
- 세션을 저장하지 않고
- 조회하지도 않습니다
즉, Stateless 인증이 됩니다.
JWT의 오해
JWT는 : 안전해 보이지만 그렇지 않습니다. 왜냐하면 암호화가 아닙니다.
Base64 인코딩 + 서명
Payload는 누구나 디코딩할 수 있습니다.
그래서 JWT에서 중요한 건
- 토큰 내용이 아니라
- 토큰을 어디에 저장하느냐입니다.
프론트엔드에서 중요한 것
localStorage에 JWT를 저장하면
- XSS 발생 시 즉시 탈취
- 만료 전까지 완전한 권한 노출
HttpOnly Cookie에 저장하면
- JS 접근 불가
- XSS 방어 가능
- 대신 CSRF 고려 필요
인증 방식보다 저장 전략이 더 중요해지는 순간입니다.
세션 vs JWT는 선택 문제가 아니다
실무에서는 이렇게 나뉩니다.
- 세션: 관리자 페이지, 내부 시스템
- JWT: 모바일, 외부 API, MSA
그리고 종종
JWT + HttpOnly Cookie + Refresh Token
같은 혼합 구조를 쓰기도합니다.
정리
- 쿠키는 출발점이었다
- 세션은 보안을 선택한 결과였다
- JWT는 확장성을 선택한 결과다