보안 시스템

[보안] JWT(Json Web Token)의 개념과 흐름

제익 2026. 4. 27. 17:23
반응형

이번 글에서는 현대 웹 서비스에서 인증/인가에 널리 사용되는 JWT(JSON Web Token)에 대해 정리해보겠다.
이전 SSO 시리즈에서 다뤘던 OAuth, OIDC에서도 토큰 기반 인증의 핵심으로 JWT가 등장한 바 있다.


1. JWT란?

JWT(JSON Web Token)는 당사자 간에 정보를 JSON 형태로 안전하게 전달하기 위한 자기 완결적(Self-Contained) 토큰 표준(RFC 7519)이다.

"자기 완결적"이라는 말은 토큰 자체에 사용자 정보와 권한 등 필요한 데이터가 모두 담겨 있다는 뜻이다. 서버가 별도로 세션을 저장하지 않아도 토큰만으로 사용자를 식별하고 검증할 수 있다.

- 세션 방식 vs JWT 방식

구분 세션(Session) 방식 JWT 방식
상태 저장 서버에 세션 저장 (Stateful) 토큰 자체에 포함 (Stateless)
서버 부하 세션 저장소 필요 별도 저장소 불필요
확장성 서버 증설 시 세션 공유 필요 수평 확장에 유리
보안 서버가 세션 직접 제어 가능 토큰 탈취 시 만료 전까지 통제 어려움

 


2. JWT 구조

JWT는 Header, Payload, Signature 세 부분으로 구성되며, 각 부분은 Base64Url로 인코딩되어 점(.)으로 구분된다.

xxxxx.yyyyy.zzzzz
  │      │      │
Header Payload Signature

📌 1) Header

토큰의 타입(JWT)과 서명에 사용할 알고리즘 정보를 담는다.

{
  "alg": "HS256",   // 서명 알고리즘 (HMAC SHA256)
  "typ": "JWT"      // 토큰 타입
}

📌 2) Payload

실제 전달하려는 데이터를 담는 부분이다. 여기에 담기는 각 항목을 클레임(Claim)이라고 한다.

클레임 종류 설명 예시
등록된 클레임 JWT 표준에서 정의한 예약된 필드 iss, sub, exp, iat
공개 클레임 충돌 방지를 위해 URI 형태로 정의 https://example.com/role
비공개 클레임 서버-클라이언트 간 합의한 커스텀 필드 userId, email

 

{
  "iss": "https://auth.example.com",   // 발급자
  "sub": "user123",                    // 사용자 식별자
  "exp": 1714000000,                   // 만료 시간 (Unix timestamp)
  "iat": 1713996400,                   // 발급 시간
  "email": "user@example.com",         // 비공개 클레임
  "role": "admin"                      // 비공개 클레임
}

* Payload는 Base64Url로 인코딩된 것이지 암호화된 것이 아니다. 누구나 디코딩하면 내용을 볼 수 있으므로, 민감한 정보(비밀번호 등)는 절대 담으면 안 된다.

📌 3) Signature

Header와 Payload를 합친 후 비밀키(Secret Key)로 서명한 값이다. 이 서명을 통해 토큰이 위변조되지 않았음을 검증한다.

HMACSHA256(
  Base64Url(Header) + "." + Base64Url(Payload),
  secretKey
)

3. JWT 인증 흐름

JWT를 이용한 일반적인 인증 흐름은 아래와 같다.

  • ① 사용자가 ID/PW로 로그인 요청
  • ② 서버가 자격증명 확인 후 Access Token(JWT) 발급
  • ③ 클라이언트는 이후 요청 시 HTTP 헤더에 토큰을 담아 전송
  • ④ 서버는 토큰의 서명을 검증하고 Payload에서 사용자 정보를 확인
  • ⑤ 인증 성공 시 요청 처리, 실패 시 401 반환
# HTTP 요청 헤더에 JWT 포함하는 방법
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

4. Access Token & Refresh Token

JWT를 실무에서 사용할 때는 보통 두 가지 토큰을 함께 운용한다.

- Access Token

실제 API 요청에 사용하는 토큰이다. 유효 기간을 짧게(보통 15분~1시간) 설정하여 탈취되더라도 피해를 최소화한다.

- Refresh Token

Access Token이 만료됐을 때 새로운 Access Token을 발급받기 위한 토큰이다. 유효 기간이 길며(보통 7일~30일) 서버 DB에 저장하여 관리한다.

구분 Access Token Refresh Token
용도 API 인증 Access Token 재발급
유효 기간 짧음 (15분~1시간) 김 (7일~30일)
저장 위치 메모리 또는 로컬 서버 DB + HttpOnly 쿠키
탈취 위험 높음 (자주 사용) 상대적으로 낮음

 


5. JWT 보안 주의사항

- alg: none 공격

일부 라이브러리는 Header의 알고리즘이 none으로 설정된 경우 서명 검증을 생략한다. 반드시 서버에서 허용할 알고리즘을 명시적으로 지정해야 한다.

- Payload 민감정보 금지

앞서 언급했듯이 Payload는 누구나 디코딩할 수 있다. 비밀번호, 카드번호 등 민감한 정보는 절대 담지 않는다.

- 토큰 저장 위치

브라우저에서 JWT를 저장할 때 localStorage는 XSS 공격에 취약하다. Refresh Token은 HttpOnly 쿠키에 저장하는 것이 권장된다.

- 짧은 만료 시간 설정

JWT는 한번 발급되면 서버에서 강제 무효화가 어렵다. Access Token의 만료 시간을 짧게 유지하고, Refresh Token 기반의 재발급 구조를 사용하는 것이 좋다.


📌 이번 글 정리

  • JWT는 Header.Payload.Signature 세 부분으로 구성된 자기 완결적 토큰이다.
  • Payload는 암호화가 아닌 Base64Url 인코딩이므로 민감정보를 담으면 안 된다.
  • 실무에서는 Access Token(단기) + Refresh Token(장기) 조합으로 운용한다.
  • 토큰은 Authorization: Bearer 헤더로 전달하는 것이 표준 방식이다.
  • 보안을 위해 알고리즘 명시, HttpOnly 쿠키 사용, 짧은 만료 시간 설정을 권장한다.

 

다음 글에서는 JWT를 실제로 Spring Boot에서 구현하는 방법을 정리해보겠다.

 

반응형

'보안 시스템' 카테고리의 다른 글

[ SSO ]의 종류 3 ‑ OpenID Connect (OIDC)  (0) 2025.07.29
[ SSO ]의 종류 2 - OAuth  (0) 2025.02.03
[ SSO ]의 종류 1 - SAML  (0) 2025.02.02
[ SSO ] 기본개념 정리  (0) 2025.02.01