프로그래밍

JWT, Security에 대해서

Retro Rat 2026. 5. 26. 16:18

1. JWT, Security가 왜 필요한가?

웹서비스는 기본적으로 "너 누구야?" 를 매 요청마다 확인해야 한다.

클라이언트 → 서버: "내 정보 줘"
서버 → 클라이언트: "너 누군데? 로그인했어?"

 

  • HTTP의 Stateless(무상태성) 특성: 웹을 구성하는 HTTP 프로토콜은 기본적으로 상태를 기억하지 못한다.
  • 인증(Authentication): 시스템에 접근하는 사람이 누구인지 확인하는 과정
  • 인가(Authorization): 인증된 사용자가 특정 리소스에 접근할 권한이 있는지 확인

→ HTTP의 무상태성을 극복하고, 사용자의 상태를 유지하며 안전하게 서비스를 제공하기 위해 우리는 인증/인가 시스템을 구축해야 한다.

 

 


2. 세션 방식 vs JWT 방식

세션 방식 (옛날 방식)

  • 사용자가 로그인하면 서버가 '세션 ID'를 발급하고, 서버 측 메모리나 DB(Redis 등)에 사용자의 정보를 저장
  • 장점
    • 서버가 모든 상태를 통제하므로, 특정 사용자 강제 로그아웃이나 동시 접속 제어 등이 매우 쉽고 안전
  • 단점
    • 사용자가 많아지면 서버의 메모리 부담이 커진다.
    • 서버가 여러 대(Scale-out)일 경우 세션을 공유하기 위한 추가적인 작업(Session Clustering 등)이 필요
1. 로그인 → 서버가 세션 저장 → 클라이언트에 세션ID 쿠키 발급
2. 요청마다 쿠키 보냄 → 서버가 세션 조회해서 확인
문제: 서버가 세션을 저장해야 해서 서버 부담 큼

 

 

JWT 방식 (요즘 표준)

  • 인증된 사용자에게 정보가 담긴 토큰을 발급하고, 서버는 상태를 저장하지 않고(Stateless), 요청이 올 때마다 토큰이 유효한지만 검증
  • 장점
    • 서버 확장에 매우 유리하며, 앱이나 웹(CORS 환경) 등 다양한 클라이언트 환경에서 범용적 사용
    • 백엔드와 프론트엔드를 분리한 REST API 구조에 적합
  • 단점
    • 한 번 발급된 토큰은 유효기간이 끝날 때까지 서버에서 강제로 만료시키기 까다롭다.
    • 토큰 자체에 데이터가 들어있어 페이로드(Payload)가 커질 수 있다.
1. 로그인 → 서버가 토큰 발급 → 클라이언트가 토큰 저장
2. 요청마다 토큰 보냄 → 서버가 토큰 검증만 함 (저장 X)
장점: 서버가 아무것도 저장 안 해도 됨

3. JWT란?

JSON Web Token 의 약자로, 클라이언트와 서버 간에 정보를 안전하고 가볍게 전송하기 위해 사용하는 웹 표준 인증(인가) 토큰 기술이다.

JWT는 .을 기준으로 세 부분으로 나뉩니다. (Header.Payload.Signature)

구조

 

  • Header: 토큰의 타입(JWT)과 암호화 알고리즘 정보
  • Payload (내용): 실제로 담고 싶은 정보(Claim)
  • Signature (서명): 서명은 서버만이 알고 있는 Secret Key를 이용해 제작해서 서명값으로 토큰 확인

 

 

 

헤더.페이로드.서명
 │      │       │
 │      │       └── 위변조 방지 서명
 │      └────────── 실제 데이터 (유저ID, 만료시간 등)
 └───────────────── 암호화 방식
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMSJ9.abc123

4. Access Token vs Refresh Token

JWT의 단점인 탈취당하면 큰일난다를 커버하기 보완하기 위한 전략으로 Access Token과 Refresh Token를 함께 사용한다.

역할

 

  • Access Token: 실제 API 요청에 사용하는 토큰으로, 유효기간을 매우 짧게(예: 15분~1시간) 설정하여 탈취당해도 피해를 최소화
  • Refresh Token: Access Token을 재발급받기 위한 용도로만 쓰이는 토큰으로, 유효기간을 길게(예: 1주~2주) 잡고, 보통 HttpOnly 쿠키나 안전한 저장소에 보관

Access Token과 Refresh Token의 차이

 

Access Token  → 실제 인증용, 수명 짧음 (1시간)
Refresh Token → Access Token 재발급용, 수명 김 (7일)

 

과정

 

1. 로그인 → Access Token + Refresh Token 발급
2. API 요청 → Access Token 헤더에 담아서 보냄
3. Access Token 만료 → Refresh Token으로 새 Access Token 발급
4. Refresh Token도 만료 → 다시 로그인

 


5. Spring Security가 하는 역할

Spring Security는 모든 요청을 가로채서 인증/인가를 처리하는 문지기야.

클라이언트 요청
      ↓
┌─────────────────────────────┐
│     Security Filter Chain   │  ← 여기서 JWT 검증
│  JwtFilter → 다음필터 → ... │
└─────────────────────────────┘
      ↓
  Controller

 

 
.authorizeHttpRequests(auth -> auth
    .requestMatchers("/auth/**").permitAll()  // 이 경로는 문지기 통과
    .anyRequest().authenticated()             // 나머지는 토큰 있어야 통과
);

6. 전체 흐름

[로그인]
FE → POST /auth/login (아이디/비밀번호)
   → BE에서 확인 후 Access Token + Refresh Token 발급
   → FE가 토큰 저장 (localStorage 또는 쿠키)

[API 요청]
FE → GET /api/mypage
     Header: Authorization: Bearer eyJhbGci...  ← Access Token
   → BE의 JwtFilter가 토큰 검증
   → 유효하면 Controller로 통과
   → 만료됐으면 401 반환

[토큰 재발급]
FE → POST /auth/refresh
     Refresh Token 보냄
   → BE가 새 Access Token 발급

 

JWT 구현 순서

1. JwtUtil 만들기        → 토큰 생성, 검증, 파싱
2. JwtFilter 만들기      → 요청마다 토큰 검증
3. SecurityConfig 수정   → JwtFilter 등록
4. 로그인 API 만들기     → 토큰 발급
5. RefreshToken 테이블   → DB에 저장