JWT, JWE access_token, refresh_token

niche·2025년 4월 22일

JWT는 정보를 안전하게 전송하기 위한 JSON 형태의 개방형 표준(RFC 7519)이다.

JWT는 세 부분으로 구성된다.
1. 헤더(Header) - 토큰 타입과 서명 알고리즘 정보
2. 페이로드(Payload) - 실제 데이터(클레임)
3. 서명(Signature) - 토큰의 유효성을 검증하기 위한 서명

이 세 부분은 점(.)으로 구분되어 있다. (xxxx.yyyy.zzzz)

JWT의 페이로드에는 다양한 클레임(claim)이 포함될 수 있다.
1. 표준 클레임 (Registered Claims)

  • exp (expiration time): 토큰 만료 시간
  • iat (issued at): 토큰 발급 시간
  • sub (subject): 토큰의 주제(일반적으로 사용자 ID)
  • iss (issuer): 토큰 발급자
  • jti (JWT iD): 토큰의 고유 식별자
  1. 사용자 정의 클레임 (Custom Claims)
  • userId: 사용자 식별자
  • role: 사용자 권한
  • name: 사용자 이름
  • 기타 응용 프로그램에 필요한 데이터

헤더와 페이로드는 단순히 Base64Url로 인코딩 되어 있어 누구나 디코딩 할 수 있다.
서명 부분만 비밀키로 생성되며, 이는 토큰이 변조되지 않았음을 검증하는 데 사용된다.

JWT는 종종 access_token으로 사용된다.
access_token은 보통 JWT 형식이며 상대적으로 짧은 수명(몇 분~몇 시간)을 가진다.
refresh_token도 JWT 형식일 수 있지만, 반드시 그럴 필요는 없다. 이는 새로운 access_token을 발급받기 위해 사용되며 더 긴 수명을 가진다.
refresh_token은 서버 측 데이터베이스에 저장되어 관리되는 경우가 많다.

JWT가 탈취되면 누구나 Base64 디코딩을 통해 페이로드의 모든 내용을 쉽게 확인할 수 있다. 이것은 일반 텍스트를 Base64로 인코딩한 것과 같으므로, 보안 관점에서는 "숨김"이 아닌 단순한 "인코딩"이다. JWT의 서명 부분만이 비밀키를 사용하여 생성되며, 이는 토큰의 내용이 변조되지 않았음을 검증하는 역할만 한다.

보안이 중요한 환경에서는 JWT 사용 시 HTTPS와 같은 암호화된 전송 프로토콜을 항상 사용해야 하며, 토큰의 유효 기간을 짧게 설정하고, 필요한 최소한의 정보만을 포함하는 것이 좋다.

페이로드를 암호화하면 보안이 향상된다. 이런 접근법을 JWE(JSON Web Encryption)라고 하며, 표준 JWT보다 더 높은 수준의 보안을 제공하게 된다.

암호화/복호화 과정은 추가적인 서버 자원을 소모한다. 표준 JWT보다 구현이 복잡해지고, 라이브러리에 따라 지원이 제한적일 수 있다. 암호화 키를 안전하게 관리해야한다.


access_token과 refresh_token은 JWT의 페이로드에 포함되는 값들이 아니라, 각각이 별도의 JWT이다.

  • access_token은 그 자체로 하나의 JWT
  • refresh_token도 그 자체로 하나의 JWT (혹은 다른 형식의 토큰)

access_token의 주요 역할은 다음과 같다.
1. 인증(Authentication): 사용자가 누구인지 증명한다.
2. 권한 부여(Authoriztion): 사용자가 어떤 리소스에 접근할 수 있는지 결정한다.
3. 상태 비저장(Stateless) 인증: 서버가 세션 상태를 유지할 필요 없이 토큰만으로 인증 처리가 가능하다.

access_token의 페이로드에는 일반적으로 다음과 같은 정보가 포함된다.

  1. 사용자 식별자(sub/userId): 누구에게 발급된 토큰인지
  2. 권한 범위(scope/permissions): 어떤 리소스에 접근할 수 있는지
  3. 만료 시간(exp): 언제까지 유효한지 (보통 짧게 설정: 15분~몇 시간)
  4. 토큰 발급자(iss): 누가 발급했는지
  5. 토큰 발급 시간(iat): 언제 발급되었는지

refresh_token은 일반적으로 다음과 같은 정보로 구성된다.

  1. 고유 식별자: UUID와 같은 랜덤하고 충분히 긴 문자열
  2. 사용자 ID: 어떤 사용자의 토큰인지 식별
  3. 만료 시간: 일반적으로 Access Token보다 훨씬 길게 설정(일/주/월 단위)
  4. 발급 시간: 언제 발급되었는지
  5. 사용 가능 횟수(선택): 한 번만 사용 가능하게 설정하는 경우도 있음

refresh_token의 최적 형식
불투명 토큰(Opaque Token)
형식: 충분히 길고 랜덤한 문자열(예: UUID v4)
장점
1. 토큰 자체에서 어떠한 정보도 유추할 수 없음
2. 서버 DB에 저장하고 조회하는 방식으로 완전한 제어 가능
3. 필요시 즉시 무효화 가능
4. 토큰 자체에 의미가 없어 보안성 향상

profile
개발이 곧 나를 만든다.

0개의 댓글