| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- 소수
- 애자일
- 프론트엔드 비대면반
- 시간 복잡도
- 멀티캠퍼스IT부트캠프티
- git branch 협업
- 재귀
- LG유플러스 유레카 3기 프론트엔드
- 브루트포스
- 별찍기10
- 멀티캠퍼스IT부트캠프
- Java
- tanstack query
- 코딩
- 백준
- Do it! 자료구조와 함께 배우는 알고리즘 입문
- LG유플러스 유레카 프론트엔드 개발자
- LG유플러스 유레카 프론트엔드
- 스레드
- 자바
- 정렬
- 프로세스
- 부트캠프후기
- 2775번 문제
- LG유플러스 유레카 부트캠프
- 알고리즘
- zod
- 웹시큐리티
- 프론트엔드
- 유레카 부트캠프
- Today
- Total
개발 일기
JWT와 Session의 개념 및 차이 본문

JWT(JSON Web Token) 방식과 Session 방식의 개념과 차이
JWT

인증 상태를 토큰 자체(클라이언트 보관)에 담아 전달한다. 서버는 보통 토큰 검증(서명 확인)만 한다. (stateless 또는 hybrid)
세션

인증 상태는 서버(또는 서버가 관리하는 스토어)에 저장된다. 서버에서 제어/무효화가 쉽다. (stateful)
아키텍처 차이
세션 (쿠키 + 세션ID)

- 로그인 성공
- 서버가 세션 생성
- 세션ID를 쿠키로 발급
- 요청마다 쿠키 전송 → 서버는 세션ID로 세션 조회 → 사용자 정보 확인
- 서버가 세션 상태(로그아웃, 만료 등)을 완전 제어
JWT (토큰 기반)

- 로그인 성공
- 서버가 서명된 JWT 발급(페이로드에 사용자 정보/만료 등 포함)
- 클라이언트가 저장(로컬 스토리지, 세션 스토리지, 쿠키 등)
- 요청마다 Authorization 헤더(Bearer <token>) 또는 쿠키로 전송 → 서버는 서명 검증, 만료 확인만으로 인증
- 서버는 발급한 JWT를 별도로 저장하거나 추적하지 않으므로 발급된 토큰을 서버에서 즉시 무효화하기가 어려움
보완 관점
토큰/세션 탈취 (XSS, 네트워크 공격)

- 세션 (쿠키)
- 쿠키 기반이라면 HttpOnly + Secure + SameSite로 보호 가능
- HttpOnly 쿠키는 JS에서 접근 불가 → XSS 공격으로부터 비교적 안전
- 네트워크에서는 HTTPS로 보호하지 않으면 탈취 위험(패킷 스니핑)
- JWT
- 저장 위치에 따라 다르다
- localStorage/sessionStorage : JS에서 접근 가능 → XSS에 매우 취약(토큰 탈취 → 즉시 계정 탈취).
- HttpOnly Cookie : JWT를 HttpOnly 쿠키로 두면 XSS로부터 보호 가능(세션과 비슷)
- JWT 자체가 XSS에 더 취약하지 않지만 실무에서는 로컬 스토리지에 두는 경우가 많아 XSS 위험이 커진다
- 저장 위치에 따라 다르다
민감한 액세스 토큰은 가능하면 HttpOnly + Secure + SameSite=Strict/Lax 쿠키로 전달해야 한다.
CSRF (Cross-Site Request Forgery)

- 세션 (쿠키)
- 쿠키는 브라우저가 자동 전송 → CSRF 취약
- 대응 : SameSite 속성, CSRF 토큰(폼/헤더 기반) 사용, Origin/Referer 검증 등
- JWT
- Authorization 헤더로 전송하면 브라우저는 자동 전송하지 않으므로 CSRF 위험 낮음
- 하지만 JWT를 쿠키(특히 자동전송되는 HttpOnly cookie)에 두면 CSRF 취약 → CSRF 방어 필요
JWT를 Authorization 헤더로 보내거나(SPA가 적합) 쿠키로 둘 땐 CSRF 토큰 또는 SameSite로 보강
토큰 무효화(Revocation) & 로그아웃
- 세션
- 서버에서 세션 삭제 한 번으로 즉시 무효화 가능하다
- JWT
- 기본 JWT는 stateless → 발급된 토큰은 만료되기 전까지 유효. 강제 무효화하려면
- 서버에 블랙리스트 보관 및 확인(stateful 사용)
- 짧은 만료시간 + 리프레시 토큰(서버에서 관리/검증) 조합
- 토큰 버전 필드를 DB에 두고 비교(사용자 비밀번호 변경 시 버전 증가하면 기존 토큰 무효화)
- 복잡도 : JWT 무효화는 설계/운영 부담이 크다.
- 기본 JWT는 stateless → 발급된 토큰은 만료되기 전까지 유효. 강제 무효화하려면
실무에서는 short-lived access token + revocable refresh token (서버에 저장) 패턴이 일반적이라고 한다.
탈취 시 피해 범위
- 세션 : 탈취된 세션ID는 세션 만료 전까지 사용 가능. 하지만 서버에서 세션 정보(예: IP, 기기, 토큰 버전)를 검사하여 제약 가능
- JWT : 토큰에 권한(scope)이 들어있다면 토큰 하나로 광범위 권한 행사 가능. 만료 기간이 길면 피해가 큼.
권장 : 최소 권한 원칙, 최소 만료 기한, refresh token rotation
세션 고정(Session Fixation)
- 세션 방식에서는 로그인 전에 부여된 세션ID를 탈취자가 고정해두고 사용자가 로그인하면 탈취자가 세션을 사용 가능 → 대응 : 로그인 시 세션ID 재생성(regenerate session id).
- JWT는 세션ID 고정 이슈가 직접적으로 없지만 발급 로직에서 취약하면 유사 문제 존재
스케일링 & 성능
- 세션 : 서버(또는 중앙 스토어)가 상태를 저장 → 수평확장 시 세션 공유가 필요
- JWT : stateless라서 검증만 하면 되어 확장 용이 → 성능/확장성 유리
단, JWT 무효화를 위해 블랙리스트/토큰 저장을 추가하면 결국 stateful이 됨.
결론
- 단순하고 안전하게 로그아웃/무효화가 필요하면 서버사이드 세션이 더 직관적이고 안전하다.
- 확장성(무상태 인증), 마이크로서비스 환경, 외부 인증(SSO) 요구가 있다면 JWT가 유리하나 반드시 짧은 accss token + 서버관리 refresh token + 안전한 저장(쿠키 + HttpOnly) 패턴을 사용해야 한다.
- 보안의 핵심은 저장 위치와 만료/회수 정책. 토큰 자체보다 어디에 저장하느냐가 더 위험을 좌우한다.
- 마지막으로 HTTPS 필수, XSS/CSRF 방어, 토큰 최소권한/짧은 수명, 로그/모니터링은 반드시 도입해야 한다.
느낀 점
완벽한 보완은 없다는 것을 느꼈고 내가 하려는 프로젝트에 어떤 것이 더 어울리고 좋은 방식일지에 대한 고민을 할 수 있는 지식을 갖추게된 시간이었다. 내용 전부를 이해할 수는 없었지만 JWT와 Session에 대한 전반적인 이해를 할 수 있어 좋았다.
'TIL' 카테고리의 다른 글
| 20251105 리액트 수업 (1) | 2025.11.05 |
|---|---|
| 20251028 사용자 경험(CX) 디자인 (0) | 2025.10.28 |
| 20251013 회원가입 암호화 (0) | 2025.10.13 |
| 20251001 uplus clone site 다시 만들기2 (0) | 2025.10.01 |
| 20250930 uplus clone site 다시 만들기 (0) | 2025.09.30 |