우와한 개발자

[JWT] JWT(JSON Web Token)란? 구조(Header, Payload, Signature)와 인증 흐름, Access Token & Refresh Token, 토큰 저장 방식

by 우와한개발자

[JWT JSON Web Token ]

1. JWT(JSON Web Token)란?

  • json형식의 데이터를 안전하게 전송하기위한 토큰
  • 주로 사용자 인증(Authentication)과 권한 부여(Authorization)에 사용
  • 서버가 사용자 정보를 바탕으로 JWT를 발급하고, 클라이언트가 이후 요청마다 JWT를 헤더에 담아보내면 서버는 이를 검증하여 인증상태를 확인

 

1) 장점

  • 서버가 세션을 저장하지 않아도 되어 Stateless 구조에 적합
  • 분산 서버 환경이나 대규모 서비스에서 확장성이 좋음
  • 요청마다 토큰만 검증하면 되므로 인증 처리 구조가 단순
  • Refresh Token과 함께 사용시 보안 강화

 

2) 단점

  • 발급된 토큰은 만료 전까지 유효하므로 강제 로그아웃 처리 어려움
  • 토큰이 탈취되면 만료 전까지 악용될 수 있음
  • 세션 방식보다 토큰 길이가 길어 요청 헤더가 커질 수 있음
  • Payload는 인코딩만 되어 있으므로 민감한 정보 저장에 부적합
  • Refresh Token, 재발급, 블랙리스트 등의 추가 설계가 필요할 수 있음

 

2. JWT 구조

  • . 으로 구분된 3개의 문자열로 구성 (xxx.yyy.zzzz 처럼..)
Header.Payload.Signature
구성 요소 설명
Header 토큰의 타입(JWT)과 서명 알고리즘(HMAC, SHA256, RSA 등)을 명시
Payload 실제 데이터 (사용자 정보, 만료 시간 등 Claims)
Signature 위 두 부분을 인코딩한 뒤, 서버의 비밀 키를 사용해 생성한 서명

 

1) Header

  • 토큰의 타입과 서명 알고리즘 정보를 담는 영역
  • 일반적으로 alg(알고리즘)과 typ(토큰 타입)으로 구성됨
{
  "alg": "HS256",
  "typ": "JWT"
}
설명
alg 서명에 사용할 암호화 알고리즘 (예: HS256, RS256)
typ 토큰 타입 (JWT)

 

2) Payload

  • JWT에 담기는 실제 데이터 영역
  • 클레임(Claim) 들로 구성
  • 클레임: key-value 쌍으로 이루어진 정보 단위
  • Payload는 Base64 인코딩만 되어 있어 누구나 디코딩할 수 있기때문에 비밀번호, 주민번호 등 민감한 정보는 절대 담지 않도록 함.
{
  "sub": "1234567890",  // 토큰의 주체(보통 사용자 식별자)
  "name": "John Doe",   // 사용자 이름
  "exp": 1710000000     // 토큰 만료 시간
}
Claim 설명
sub (Subject) 토큰의 주체 (보통 사용자 ID)
iss (Issuer) 토큰 발급자
aud (Audience) 토큰 대상자
exp (Expiration) 토큰 만료 시간
iat (Issued At) 토큰 발급 시간

 

3) Signature

  • 토큰의 위변조 방지를 위한 서명 영역
  • Header와 Payload를 기반으로 생성됨
  • 서버만 알고 있는 secret key로 생성
HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

 

3. JWT 인증 방식 흐름

로그인 요청 (ID + PW)
→ 서버에서 사용자 검증 (DB 조회 + 비밀번호 확인)
→ 검증 성공 시 JWT 발급 (Access Token [+ Refresh Token])
→ 클라이언트가 토큰 저장 (localStorage, HttpOnly Cookie 등)
→ 이후 API 요청 시 Authorization 헤더에 JWT 포함 (Authorization: Bearer <token>)
→ 서버가 JWT 서명 및 만료 여부 검증
→ 인증 완료 → 요청 처리

 

4. Access Token & Refresh Token

  • 실무에서 주로 Access Token와 Refresh Token을 함께 사용
구분 Access Token Refresh Token
목적 API 호출 인증에 사용 Access Token 재발급에 사용
유효 기간 짧게 설정 (ex. 30분 ~ 1시간) 길게 설정 (ex. 7일 ~ 30일)
저장 위치 메모리 또는 localStorage HttpOnly Cookie 권장
탈취 위험 높음 (요청마다 포함) → 짧은 유효기간으로 보완 낮음 (재발급 시에만 사용)

 

  • Refresh Token 동작 흐름
1. 로그인 → Access Token + Refresh Token 발급
2. API 요청 → Access Token 포함
3. Access Token 만료 → 401 Unauthorized 응답
4. 클라이언트가 Refresh Token으로 /auth/refresh 요청
5. 서버가 Refresh Token 검증 → 새로운 Access Token 발급
6. 클라이언트가 새 Access Token으로 재요청

 

 

[ 인증 토큰 저장/관리 방식 ]

1. 메모리 저장

  • 토큰을 JavaScript 변수(메모리)에만 저장하는 방식
  • 장점 : XSS 공격으로 탈취될 위험 낮음
  • 단점 : 페이지를 새로고침하면 값이 사라짐.

 

2. HttpOnly 쿠키

  • 토큰을 브라우저 쿠키에 저장하는 방식
  • 장점 : XSS 공격으로 탈취될 위험 낮음(JavaScript로 쿠키에 접근 불가하기 때문)
  • 단점 : CSRF(Cross-SiteRequestForgery)공격에 취약(SameSite 쿠키 속성을 추가로 사용해 보완)

 

3. Secure WebSocket

  • 웹소켓 연결을 통해 JWT를 전송하고, 연결이 유지되는 동안 인증 상태를 유지하는 방식
  • 장점 : HTTPS 와 마찬가지로 암호화된 연결로 토큰 안전하게 전송 가능
  • 단점 : 웹소켓 연결이 끊어지면 토큰 정보도 사라지고 웹소켓 구현이 복잡함

 

4. OAuth2 Token Management

  • Access Token과 Refresh Token을 함께 사용하는 인증 방식
    • Access Token : API 호출 시 사용 (짧은 유효기간)
    • Refresh Token : Access Token 재발급용 (긴 유효기간)
  • 장점 : 토큰 탈취 시 피해를 최소화할 수 있음 (짧은 수명,재발급 구조)
  • 단점 : Refresh Token 저장/관리 로직이 추가되어 구현 복잡도 증가

 

5. localStorage/sessionStorage

  • 브라우저 저장소에 토큰을 저장하는 방식
    • localStorage : 브라우저 종료 후에도 유지
    • sessionStorage : 탭 종료 시 삭제
  • 장점 : 구현이 간단하고 사용하기 편리함
  • 단점 : XSS 공격 시 토큰 탈취 가능(JavaScript로 접근 가능)

 

6. IndexedDB/WebSQL

  • 브라우저 내부 DB에 토큰을 저장하는 방식
  • 장점 : 대용량 데이터 저장 가능
  • 단점 : XSS 공격 시 토큰 탈취 가능(JavaScript로 접근 가능)
  • 토큰 저장 용도로는 거의 사용되지 않음

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기