본문 바로가기
2025 Dev Log/CS

[#3][개념 정리 #3][네트워크] JWT 구조

by Dev.후크리 2025. 9. 17.
1. 개념 설명 (Concept)

 

JWT (JSON Web Token) = JSON 포맷으로 사용자의 인증/인가 정보를 담아, 암호화된 서명과 함께 전달하는 토큰.

구조:

 
Header.Payload.Signature
  • Header (헤더): 토큰 타입(JWT)과 해싱 알고리즘(HS256 등)
  • Payload (페이로드): 사용자 정보(Claim) → ID, 권한, 만료 시간 등
  • Signature (서명): Header+Payload를 비밀키로 해싱한 값 (변조 방지 역할)

2. 올바른 용어 (Terminology)
  • Claim (클레임): 토큰에 담긴 정보 조각 (예: sub: userId, role: admin)
  • exp (만료시간, Expiration Time): 토큰이 유효한 시간
  • HS256: HMAC + SHA256 알고리즘 (대칭키)
  • RS256: RSA + SHA256 (비대칭키)
  • Bearer Token (베어러 토큰): HTTP 요청의 Authorization 헤더에 담기는 방식 → Authorization: Bearer <JWT>

 


3. 잘못 쓰기 쉬운 표현 + 실제 맥락 (Misuse & Context)

 

❌ “JWT는 암호화돼서 안전하다” → 틀림

  • Payload는 Base64 인코딩일 뿐이라 누구나 열어볼 수 있음.
  • 보안은 **Signature(서명)**가 책임집니다.

✅ 현업에서는

  • 민감 정보(비밀번호, 주민번호)는 Payload에 절대 넣지 않고,
  • 보통은 userId, role, exp 정도만 담습니다.

 


몰랐던 부분

 

1, JWT 검증 시 서버가 DB를 쓰는가 안 쓰는가?

 


1. 서버에서 토큰 인증(검증)할 때 무슨 일이 일어나나?

JWT가 들어오면 서버는 이렇게 처리합니다:

Authorization 헤더에서 토큰 추출 Authorization: Bearer <JWT> 토큰을 . 기준으로 분리 → Header, Payload, Signature 서버는 자신이 가지고 있는 secret key로 (Header + Payload) 를 다시 해싱해서 Signature와 비교 일치하면 “위변조 안 됨”으로 인정 ✅ Payload 안의 userId, role, exp 같은 Claim 확인 후 접근 허용

👉 이때는 DB 조회 없이도 “이 토큰이 내 서버가 발급한 진짜 맞음”을 알 수 있어요.



2. DB를 꼭 안 쓰는 건 아니다

JWT의 장점은 DB를 매번 조회하지 않아도 사용자 인증이 가능하다는 점이에요. 하지만 다음과 같은 경우 DB를 쓸 수밖에 없음: 로그아웃 처리: 이미 발급된 토큰을 강제로 무효화하려면 → 블랙리스트(DB/Redis)에 저장해야 함 권한(Role) 변경: 사용자가 일반회원 → 관리자 승격되었는데, 예전 JWT는 여전히 ROLE_USER임 → 새 토큰 발급 or DB 확인 필요 Refresh Token 전략: Access Token은 짧게, Refresh Token은 DB/Redis에 저장해서 관리



3. 정리

평소 요청 검증: DB 안 씀 (secret key로 Signature만 확인) 특수 상황(로그아웃, 권한 변경, Refresh Token 관리): DB 또는 Redis 필요

 


2, 매 토큰, 계정마다 새로운 시크릿 키를 쓰는게 아니라 서버당 하나의 시크릿 키로 모든 토큰을 열 수 있다.

 


JWT는 매번 새로운 secret key를 발급하는 게 아니고, 서버마다(or 서비스마다) 하나의 secret key를 가지고 계속 쓰는 구조



1. 왜 secret key가 하나로 충분할까?

JWT의 Signature는 이렇게 만들어집니다:

Signature = HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secretKey )

즉, 같은 secretKey를 쓰면, 서버는 언제든지 Header+Payload를 가지고 Signature를 다시 계산할 수 있어요. 클라이언트가 보낸 JWT의 Signature와 비교 → 일치하면 “내가 발급한 것”임을 확인 가능.

👉 그래서 서버마다 고정된 secretKey를 가지고 있어야, 발급한 모든 토큰을 검증할 수 있습니다.



2. 비밀키(Secret Key) 관리 방식

일반적으로 환경 변수 / config 파일에 저장하고, GitHub 같은 저장소에 절대 올리면 안 됨 ❌ 서비스 규모가 커지면 여러 서버가 같은 토큰을 검증해야 하므로, 모든 서버가 동일한 secret key를 공유합니다. 더 큰 규모(은행, 정부 수준)에서는 대칭키(HS256) 대신 **비대칭키(RS256, 공개키/개인키)**를 써서 관리합니다.



3. 정리

✔ secret key는 서버(혹은 서비스) 당 하나를 계속 씀
✔ secret key는 토큰 발급과 검증에 모두 필요
✔ secret key가 바뀌면, 이전 토큰은 모두 무효화됨 (서명 검증이 실패하기 때문에)