Skip to main content

Session vs Token 전략

작성일: 2025.10.01

Intro

1. 인증 방식, 무엇을 선택할까?

Spring Security를 구성할 때 가장 먼저 마주하는 아키텍처 결정 중 하나는 "사용자의 로그인 상태를 어디에 저장하고 어떻게 유지할 것인가?" 입니다. 이는 크게 Server Based(Session) 방식과 Client Based(Token) 방식으로 나뉩니다.

각 방식의 특징과 장단점을 비교하고, 우리 프로젝트에서는 왜 Session + Redis 조합을 선택했는지 정리해 봅니다.


2. Session vs Token 상세 비교

🟢 Session

전통적인 웹 서비스 방식입니다. 서버가 **"모든 것을 기억"**합니다.

핵심 메커니즘
  1. 저장: 서버의 메모리(혹은 외부 저장소)에 로그인/인증 정보를 저장합니다.
  2. 전송: 클라이언트는 JSESSIONID와 같은 세션 ID만 쿠키로 들고 다닙니다.
  3. 검증: 요청이 올 때마다 서버는 세션 ID를 통해 자신이 가지고 있는 정보와 매칭하여 유효성을 검사합니다.
  • 장점

    • 강력한 상태 제어: 서버가 로그인 정보를 쥐고 있으므로, 강제 로그아웃, 계정 차단, 세션 만료 등을 즉각적으로 처리할 수 있습니다.
    • 보안성: 중요한 정보는 모두 서버에 있고, 클라이언트는 의미 없는 ID 값만 가집니다.
    • 편의성: Spring Security를 포함한 대부분의 웹 프레임워크가 기본적으로 지원하여 구현이 쉽습니다.
  • 단점

    • 확장성(Scalability) 이슈: 서버가 여러 대(Scale-out)일 경우, 각 서버 간 세션 정보를 공유해야 하는 문제(세션 불일치)가 발생합니다. -> 별도의 세션 저장소(Redis 등) 필요
    • 리소스 부담: 동시 접속자가 늘어날수록 서버의 메모리/저장소 부담이 커집니다.
    • Stateful: 서버가 반드시 클라이언트의 상태를 기억하고 있어야 합니다.

🟠 Token (JWT)

최근 MSA 환경에서 주로 사용되는 방식입니다. 서버는 "검증만 할 뿐, 기억하지 않습니다."

핵심 메커니즘
  1. 발급: 로그인 성공 시 서버가 사용자 정보가 담긴 암호화된 **토큰(JWT)**을 발급합니다.
  2. 전송: 클라이언트는 요청 시 헤더(Authorization: Bearer ...)에 토큰을 담아 보냅니다.
  3. 검증: 서버는 토큰의 서명(Signature) 만 확인하여 위변조 여부를 체크합니다. (별도 저장소 조회 X)
  • 장점

    • 완전한 Stateless: 서버에 세션 정보를 저장할 필요가 없습니다.
    • 뛰어난 확장성: 서버를 무한히 늘려도(Scale-out), 토큰 검증 로직만 있다면 어느 서버든 처리가 가능합니다.
    • 호환성: 모바일 앱, SPA(React/Vue), 다른 도메인 간의 SSO(Single Sign-On) 구현에 유리합니다.
  • 단점

    • 제어의 어려움: "이미 발급된 토큰은 뺏을 수 없다." 토큰이 탈취되더라도 유효기간이 끝날 때까지 막을 방법이 마땅치 않습니다. (Blacklist 관리가 필요해짐)
    • 네트워크 트래픽: 토큰에 많은 정보를 담을수록 HTTP 헤더 사이즈가 커져 트래픽이 증가합니다.

3. 언제 무엇을 써야 할까?

어떤 방식이 '무조건' 좋다는 없습니다. 프로젝트의 성격에 따라 선택해야 합니다.

구분Session 권장Token (JWT) 권장
서비스 유형전통적 웹 서비스, 내부 어드민 시스템MSA, 모바일 앱, SPA, 글로벌 서비스
인프라 환경단일 서버 혹은 소규모 클러스터오토스케일링이 잦은 클라우드/분산 환경
필요 기능강제 로그아웃, 실시간 동시 접속 제어SSO, 다양한 클라이언트(Web/App) 지원
핵심 가치보안 및 중앙 제어 (Control)확장성 및 유연성 (Scalability)
한 줄 요약

"엄격한 관리와 보안이 필요한 웹 기반 내부 서비스에는 Session, 대규모 트래픽과 다양한 클라이언트 확장이 필요한 B2C 서비스에는 Token이 더 적합합니다."


4. Session + Redis 조합

> 왜 Session을 선택했나?

이전 프로젝트에서 저는 Session 기반 인증을 선택했습니다.

  1. 단일 도메인 환경: 현재 시스템은 비교적 단일 도메인(Same Origin) 환경에서 동작하므로 쿠키 기반의 세션 처리가 가장 효율적입니다.
  2. 강력한 보안 제어 요구: 관리자가 악성 사용자를 즉시 강제 로그아웃 시키거나, 중복 로그인을 방지하는 등 서버 측의 상태 제어가 필수적이었습니다. JWT로는 이를 구현하기 위해 Blacklist를 도입해야 하는 등 배보다 배꼽이 더 커질 수 있습니다.
  3. 구현의 용이성: Spring Security의 기본 설정이 세션 기반이므로, 빠르고 안정적인 보안 시스템 구축이 가능했습니다.

> 단점 극복: Redis를 활용한 세션 클러스터링

세션 방식의 치명적인 단점인 "확장성(서버 간 세션 불일치)" 문제는 Redis를 도입하여 해결했습니다.

  • 문제 상황: WAS(Web Application Server)를 2대 이상으로 증설할 경우, A 서버에서 로그인한 사용자가 B 서버로 요청을 보내면 로그인이 풀리는 현상 발생.
  • 해결책 (Redis Session Storage):
    • 각 서버의 로컬 메모리가 아닌, 외부의 초고속 인메모리 DB인 Redis에 세션을 저장합니다.
    • Spring Session Data Redis를 사용하면 설정 몇 줄로 이 아키텍처를 구현할 수 있습니다.
    • 이제 사용자가 어떤 서버에 접속하든, Redis에서 동일한 세션 정보를 참조하므로 로그인 상태가 유지됩니다.

세션의 안정성/보안성은 챙기면서, Redis를 통해 확장성의 한계를 극복하는 하이브리드 전략을 취했습니다.

5. 마치며

결국 "어떤 기술이 더 우월한가?"보다는 "현재 우리 서비스의 요구사항에 무엇이 더 적합한가?" 가 의사결정의 핵심이었습니다. 이번 아키텍처 설계를 통해 단순히 기능을 구현하는 것을 넘어, 기술의 트레이드오프를 고려하여 최적의 해답을 찾아가는 과정의 중요성을 배울 수 있었습니다.