[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로 접근 가능)
- 토큰 저장 용도로는 거의 사용되지 않음
'프레임워크 > Spring' 카테고리의 다른 글
블로그의 정보
우와한개발자 님의 블로그
우와한개발자