RFC 7519

RFC 7519는 JSON Web Token(JWT)에 대한 공식 인터넷 표준 문서이다.
2015년 5월에 Internet Engineering Task Force(IETF)에 의해 발행된 이 문서는 JWT의 구조, 형식, 서명 방법, 암호화 방법 등을 상세히 정의하고 있다. JWT는 당사자 간에 안전하게 정보를 전송하기 위한 간결하고 자체 포함적인 방법을 제공하는 개방형 표준이다.

JWT는 현대 웹 애플리케이션과 마이크로서비스 아키텍처에서 인증 및 정보 교환을 위한 핵심 기술로 자리 잡았다. 특히 Single Sign-On(SSO), API 인증, 정보의 안전한 전송 등 다양한 사용 사례에서 널리 활용되고 있다.

RFC 7519는 Michael B. Jones, John Bradley, Nat Sakimura가 작성했으며, JWT의 기반이 되는 JSON Web Signature(JWS, RFC 7515) 및 JSON Web Encryption(JWE, RFC 7516) 표준과 밀접하게 연관되어 있다.

JWT의 기본 개념과 구조

JWT의 정의

JWT는 당사자 간에 클레임(claim)을 안전하게 표현하기 위한 컴팩트하고 URL-safe한 수단이다. 클레임이란 어떤 주체(subject)에 대한 진술이나 정보를 의미한다. 예를 들어, 사용자의 신원, 권한, 또는 기타 데이터 등이 클레임에 포함될 수 있다.

JWT의 기본 구조

JWT는 세 부분으로 구성되며, 각 부분은 점(.)으로 구분된다:

1
xxxxx.yyyyy.zzzzz

이 세 부분은 각각 다음과 같다:

  1. 헤더(Header): JWT의 유형과 사용된 서명 알고리즘을 지정한다.
  2. 페이로드(Payload): 전송하려는 클레임들을 포함한다.
  3. 서명(Signature): 토큰의 무결성을 검증하기 위한 서명 부분이다.

각 부분은 Base64Url로 인코딩되어 있어, URL에서 안전하게 사용할 수 있다.

헤더(Header)

헤더는 일반적으로 두 가지 정보를 담고 있다:

  • typ (Type): 토큰의 유형을 지정한다. 일반적으로 “JWT"이다.
  • alg (Algorithm): 서명 생성에 사용된 알고리즘을 지정한다. 예: HMAC SHA256 (HS256), RSA SHA256 (RS256) 등

예시:

1
2
3
4
{
  "alg": "HS256",
  "typ": "JWT"
}

페이로드(Payload)

페이로드는 토큰이 전달하려는 클레임들을 포함한다.

RFC 7519는 클레임을 세 가지 유형으로 분류한다:

  1. 등록된 클레임(Registered Claims): 미리 정의된 클레임으로, 필수는 아니지만 권장된다.
    • iss (Issuer): 토큰 발급자
    • sub (Subject): 토큰 제목
    • aud (Audience): 토큰 대상자
    • exp (Expiration Time): 토큰 만료 시간
    • nbf (Not Before): 이 시간 이전에는 토큰이 유효하지 않음
    • iat (Issued At): 토큰 발급 시간
    • jti (JWT ID): 토큰의 고유 식별자
  2. 공개 클레임(Public Claims): JWT 사용자가 정의할 수 있지만, 충돌 방지를 위해 IANA JSON Web Token Registry에 등록하거나 충돌 방지 이름(Collision-Resistant Name)을 포함해야 한다.
  3. 비공개 클레임(Private Claims): 사용 당사자 간에 정보를 공유하기 위해 생성된 맞춤형 클레임이다.

예시:

1
2
3
4
5
6
7
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022,
  "exp": 1516242622
}

서명(Signature)

서명은 JWT의 무결성을 검증하고 발신자를 인증하는 데 사용된다. 서명은 인코딩된 헤더, 인코딩된 페이로드, 비밀 키, 헤더에 지정된 알고리즘을 사용하여 생성된다.

예를 들어, HMAC SHA256 알고리즘을 사용하는 경우:

1
2
3
4
5
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

이 서명은 메시지가 도중에 변경되지 않았는지 확인하는 데 사용되며, 비밀 키로 서명된 토큰의 경우 발신자의 신원도 확인할 수 있다.

JWT의 서명 및 암호화 알고리즘

RFC 7519는 JWT의 서명과 암호화를 위한 여러 알고리즘을 지원한다.

서명 알고리즘

JWT는 다양한 서명 알고리즘을 지원하며, 주요 알고리즘은 다음과 같다:

  1. HMAC(Hash-based Message Authentication Code) 알고리즘:
    • HS256: HMAC using SHA-256
    • HS384: HMAC using SHA-384
    • HS512: HMAC using SHA-512
  2. RSA(Rivest-Shamir-Adleman) 알고리즘:
    • RS256: RSA Signature with SHA-256
    • RS384: RSA Signature with SHA-384
    • RS512: RSA Signature with SHA-512
  3. ECDSA(Elliptic Curve Digital Signature Algorithm) 알고리즘:
    • ES256: ECDSA using P-256 curve and SHA-256
    • ES384: ECDSA using P-384 curve and SHA-384
    • ES512: ECDSA using P-521 curve and SHA-512
  4. 무서명 JWT:
    • none: 서명 없음 (보안상의 이유로 일반적으로 권장되지 않음)

각 알고리즘의 특징 및 적용 사례

  1. HMAC 기반 알고리즘:
    • 대칭 암호화 방식으로, 동일한 비밀 키를 사용하여 서명 생성 및 검증
    • 구현이 간단하고 빠른 성능
    • 주로 단일 시스템 내에서 사용되거나 안전하게 비밀 키를 공유할 수 있는 경우에 적합
    • 사용 사례: 동일한 조직 내 서비스 간 통신
  2. RSA 기반 알고리즘:
    • 비대칭 암호화 방식으로, 개인 키로 서명을 생성하고 공개 키로 검증
    • 키 배포가 더 안전함 (공개 키는 공개적으로 공유 가능)
    • 상대적으로 더 많은 컴퓨팅 리소스 필요
    • 사용 사례: 여러 클라이언트가 토큰을 검증해야 하는 공개 API
  3. ECDSA 기반 알고리즘:
    • 비대칭 암호화 방식으로, RSA와 유사하지만 더 작은 키 크기로 동등한 보안 제공
    • 더 높은 성능과 더 작은 서명 크기
    • 사용 사례: 모바일 애플리케이션, IoT 디바이스 등 리소스 제약이 있는 환경

암호화 알고리즘

JWT는 JWE(JSON Web Encryption) 사양을 통해 페이로드 암호화를 지원한다.

주요 암호화 알고리즘은 다음과 같다:

  1. 키 암호화 알고리즘:
    • RSA1_5: RSAES-PKCS1-v1_5
    • RSA-OAEP: RSAES OAEP using default parameters
    • A128KW, A192KW, A256KW: AES Key Wrap with 128, 192, 256-bit keys
  2. 콘텐츠 암호화 알고리즘:
    • A128CBC-HS256: AES CBC mode with HMAC SHA-256
    • A192CBC-HS384: AES CBC mode with HMAC SHA-384
    • A256CBC-HS512: AES CBC mode with HMAC SHA-512
    • A128GCM, A192GCM, A256GCM: AES GCM mode with 128, 192, 256-bit keys

암호화된 JWT(JWE)는 다섯 부분으로 구성되며, 각 부분은 점(.)으로 구분된다:

1
header.encrypted_key.initialization_vector.ciphertext.authentication_tag

JWT의 보안 고려사항

RFC 7519는 JWT 사용 시 고려해야 할 여러 보안 사항을 명시하고 있다.

알고리즘 선택과 관련된 보안 문제

  1. 알고리즘 강제(Algorithm Forcing) 공격:
    • 공격자가 alg 값을 none으로 변경하여 서명 검증을 우회하려는 시도
    • 방어: none 알고리즘 사용을 명시적으로 금지하고, 예상되는 알고리즘을 강제 적용
  2. 알고리즘 교체(Algorithm Substitution) 공격:
    • 공격자가 알고리즘을 대칭키(HMAC)에서 비대칭키(RSA)로 변경하여 공개키를 비밀키로 사용하게 하는 공격
    • 방어: 토큰 검증 시 사용할 알고리즘을 미리 결정하고 고정

토큰 수명 관리

  1. 만료 시간 설정:
    • 모든 JWT에 적절한 만료 시간(exp 클레임)을 설정해야 함
    • 애플리케이션 요구사항에 따라 짧게(몇 분에서 몇 시간) 설정하는 것이 좋음
  2. 토큰 갱신(Refresh) 메커니즘:
    • 짧은 만료 시간을 가진 액세스 토큰과 더 긴 만료 시간을 가진 갱신 토큰의 조합 사용
    • 액세스 토큰이 만료되면 갱신 토큰을 사용하여 새 액세스 토큰 발급

토큰 저장 및 전송

  1. 클라이언트 측 저장:
    • httpOnly 플래그가 설정된 쿠키에 저장(XSS 공격으로부터 보호)
    • Secure 플래그를 사용하여 HTTPS를 통해서만 전송
    • SameSite 속성을 설정하여 CSRF 공격 방지
  2. 토큰 전송:
    • Authorization 헤더를 통한 전송: Authorization: Bearer <token>
    • 쿼리 파라미터로 전송하는 것은 보안상 권장되지 않음(로그에 노출될 수 있음)

페이로드 보안

  1. 민감한 정보 처리:

    • JWT의 페이로드는 단순히 Base64Url로 인코딩되어 있어 누구나 디코딩할 수 있음
    • 비밀번호, 개인식별정보 등 민감한 정보는 포함하지 않아야 함
    • 민감한 정보가 필요한 경우 JWE를 사용하여 페이로드 전체를 암호화해야 함
  2. 토큰 크기 관리:

    • 페이로드에 너무 많은 정보를 포함하면 토큰 크기가 커져 성능에 영향을 미칠 수 있음
    • 필요한 최소한의 정보만 포함하는 것이 좋음

서명 검증

  1. 서명 무결성 보장:
    • 모든 JWT 검증 시 서명을 철저히 검증해야 함
    • 서명 검증을 건너뛰지 않도록 주의
  2. 키 관리:
    • 서명 및 암호화에 사용되는 키를 안전하게 관리
    • 정기적인 키 교체(rotation) 메커니즘 구현

JWT 클레임(Claims)의 상세 설명

RFC 7519는 JWT에서 사용할 수 있는 여러 표준 클레임을 정의하고 있습니다. 이러한 클레임은 토큰에 대한 메타데이터와 조건을 제공합니다.

5.1 등록된 클레임(Registered Claims)

등록된 클레임은 상호 운용성을 위해 IANA JWT Claims Registry에 등록된 미리 정의된 클레임입니다:

  1. iss (Issuer):

    • 토큰을 발행한 주체(발급자)를 식별
    • 일반적으로 URL 형식의 문자열(예: “https://auth.example.com”)
    • 수신자는 이 값을 사용하여 특정 발급자로부터의 토큰만 수락하도록 제한 가능
  2. sub (Subject):

    • 토큰이 나타내는 주체(일반적으로 사용자)를 식별
    • 발급자 내에서 고유해야 함(예: 사용자 ID)
    • 수신자는 이 값을 사용하여 특정 사용자와 관련된 작업을 수행
  3. aud (Audience):

    • 토큰의 의도된 수신자를 식별
    • 문자열 또는 문자열 배열 가능
    • 수신자는 자신이 이 목록에 포함되어 있는지 확인해야 함
  4. exp (Expiration Time):

    • 토큰이 만료되는 시간(NumericDate 형식, Unix 시간(초))
    • 이 시간 이후에는 토큰이 거부되어야 함
    • 약간의 시계 편차(일반적으로 몇 분)를 허용하는 것이 좋음
  5. nbf (Not Before):

    • 토큰이 유효해지는 시작 시간(NumericDate 형식)
    • 이 시간 이전에는 토큰이 거부되어야 함
    • 미래 시간으로 설정하여 토큰의 사용을 지연시킬 수 있음
  6. iat (Issued At):

    • 토큰이 발행된 시간(NumericDate 형식)
    • 토큰의 나이를 결정하는 데 사용 가능
    • 토큰 갱신 정책에 활용 가능
  7. jti (JWT ID):

    • 토큰의 고유 식별자
    • 중복 처리, 재생 공격 방지 등에 사용
    • 발급자는 각 토큰에 고유한 값을 할당해야 함

5.2 공개 클레임(Public Claims)

공개 클레임은 JWT 사용자가 정의할 수 있지만, 이름 충돌을 방지하기 위한 조치가 필요합니다:

  1. IANA JWT Claims Registry에 등록:

    • 표준화된 클레임 사용을 위해 공식 레지스트리에 등록
    • 예: name, email, preferred_username
  2. 충돌 방지 이름(Collision-Resistant Name) 사용:

    • 도메인 이름을 접두사로 사용(예: https://example.com/claims/role)
    • URI 형식으로 정의하여 충돌 방지

공개 클레임의 예:

1
2
3
4
5
{
  "name": "John Doe",
  "email": "john.doe@example.com",
  "https://example.com/roles": ["admin", "user"]
}

5.3 비공개 클레임(Private Claims)

비공개 클레임은 당사자 간에 합의된 정보를 공유하기 위한 맞춤형 클레임입니다:

  • 등록된 클레임이나 공개 클레임과 충돌하지 않는 이름 사용
  • 발급자와 소비자 간에 의미가 이해되어야 함
  • 일반적으로 특정 애플리케이션이나 컨텍스트에 한정된 정보

비공개 클레임의 예:

1
2
3
4
5
6
{
  "user_id": 123456,
  "role": "manager",
  "organization": "Engineering",
  "permissions": ["read", "write", "delete"]
}

6. JWT 사용 패턴 및 모범 사례

RFC 7519와 업계 모범 사례를 기반으로 한 JWT의 효과적인 사용 패턴을 살펴보겠습니다.

6.1 인증 및 권한 부여 패턴

  1. 액세스 토큰/갱신 토큰 패턴:

    • 짧은 수명의 액세스 토큰(몇 분몇 시간)과 긴 수명의 갱신 토큰(며칠몇 주) 사용
    • 액세스 토큰이 만료되면 갱신 토큰을 사용하여 새 액세스 토큰 발급
    • 갱신 토큰은 데이터베이스에 저장하고 필요시 취소 가능하게 관리
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    클라이언트                             서버
       |                                   |
       |-- 로그인 (username, password) --> |
       |                                   |
       |<-- 액세스 토큰 + 갱신 토큰 ------| 
       |                                   |
       |-- 요청 + 액세스 토큰 -----------> |
       |<-- 응답 ------------------------- |
       |                                   |
       |-- 요청 + 만료된 액세스 토큰 ----> |
       |<-- 401 Unauthorized ------------- |
       |                                   |
       |-- 갱신 요청 + 갱신 토큰 --------> |
       |<-- 새 액세스 토큰 + 새 갱신 토큰 -|
       |                                   |
    
  2. 상태 비저장(Stateless) JWT vs. 상태 저장(Stateful) JWT:

    • 상태 비저장: 토큰에 모든 필요한 정보 포함, 서버에 저장 안 함
      • 장점: 확장성 좋음, 데이터베이스 조회 불필요
      • 단점: 토큰 취소 어려움, 크기가 클 수 있음
    • 상태 저장: 토큰에 최소한의 정보만 포함하고 서버에 나머지 정보 저장
      • 장점: 토큰 취소 용이, 작은 토큰 크기
      • 단점: 데이터베이스 조회 필요, 복잡한 구현
  3. 자체 포함(Self-contained) 권한:

    • JWT에 사용자 역할, 권한 등을 포함하여 별도 조회 없이 권한 부여 결정

    • 예:

      1
      
      {  "sub": "1234567890",  "roles": ["admin", "editor"],  "permissions": ["read:users", "write:users"]}
      

6.2 토큰 관리 모범 사례

  1. 적절한 만료 시간 설정:

    • 액세스 토큰: 15분~2시간 (보안 요구사항에 따라 조정)
    • 갱신 토큰: 7일~30일 (필요에 따라 조정)
    • 위험도가 높은 작업은 더 짧은 만료 시간 적용
  2. 토큰 취소 메커니즘:

    • 블랙리스트: 취소된 토큰의 jti를 저장하여 검증 시 확인
    • 화이트리스트: 유효한 토큰만 목록에 유지
    • Redis와 같은 인메모리 데이터 저장소 사용 권장
  3. 키 관리(Key Management):

    • 정기적인 키 교체(rotation) 구현 (일반적으로 3~6개월마다)
    • 키 ID(kid) 헤더 파라미터 사용하여 여러 키 관리
    • HSM(Hardware Security Module) 또는 KMS(Key Management Service) 사용 권장
  4. 토큰 크기 최적화:

    • 필요한 최소한의 클레임만 포함
    • 긴 클레임 이름 대신 짧은 이름 사용 고려
    • 중요한 메타데이터에만 등록된 클레임 사용

6.3 보안 강화 방법

  1. 서명 알고리즘 권장사항:

    • 대칭 키: HS256 이상 사용(HS384, HS512 권장)
    • 비대칭 키: RS256 이상 또는 ES256 이상 권장
    • 알고리즘 없음("alg": "none")은 절대 사용 금지
  2. 토큰 사용 제한:

    • aud 클레임을 사용하여 특정 서비스만 토큰을 사용하도록 제한
    • scope 또는 scp 클레임을 사용하여 토큰의 권한 범위 제한
  3. CSRF 및 XSS 방어:

    • JWT를 httpOnlySecure 플래그가 설정된 쿠키에 저장
    • SameSite=Strict 또는 SameSite=Lax 쿠키 설정 사용
    • 브라우저 내 스토리지(localStorage, sessionStorage)를 사용할 경우 XSS 대비 강화
  4. 토큰 무결성 검증:

    • 모든 필수 클레임 존재 여부 검증
    • 예상되는 발급자(iss), 대상(aud) 확인
    • 토큰 유형(typ) 확인

JWT 구현 예제

다양한 프로그래밍 언어에서 JWT를 구현하는 방법

Node.js에서의 JWT 구현

jsonwebtoken 라이브러리를 사용한 예제:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
const jwt = require('jsonwebtoken');

// JWT 생성
function generateToken(user) {
  const payload = {
    sub: user.id,
    name: user.name,
    email: user.email,
    roles: user.roles,
    iat: Math.floor(Date.now() / 1000),
    exp: Math.floor(Date.now() / 1000) + (60 * 60) // 1시간 후 만료
  };
  
  return jwt.sign(payload, process.env.JWT_SECRET, { algorithm: 'HS256' });
}

// JWT 검증
function verifyToken(token) {
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET, {
      algorithms: ['HS256'] // 허용할 알고리즘 명시적 지정
    });
    return { valid: true, data: decoded };
  } catch (err) {
    return { valid: false, error: err.message };
  }
}

// 미들웨어로 사용 예
function authMiddleware(req, res, next) {
  const authHeader = req.headers.authorization;
  
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ message: 'Authentication required' });
  }
  
  const token = authHeader.split(' ')[1];
  const result = verifyToken(token);
  
  if (!result.valid) {
    return res.status(401).json({ message: 'Invalid token' });
  }
  
  req.user = result.data;
  next();
}

Python에서의 JWT 구현

PyJWT 라이브러리를 사용한 예제:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import jwt
import datetime
import os
from functools import wraps
from flask import Flask, request, jsonify

app = Flask(__name__)
JWT_SECRET = os.environ.get('JWT_SECRET', 'default-secret')

# JWT 생성
def generate_token(user):
    payload = {
        'sub': str(user['id']),
        'name': user['name'],
        'email': user['email'],
        'roles': user['roles'],
        'iat': datetime.datetime.utcnow(),
        'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
    }
    
    return jwt.encode(payload, JWT_SECRET, algorithm='HS256')

# JWT 검증
def verify_token(token):
    try:
        return jwt.decode(token, JWT_SECRET, algorithms=['HS256'])
    except jwt.ExpiredSignatureError:
        return None  # 토큰 만료
    except jwt.InvalidTokenError:
        return None  # 유효하지 않은 토큰

# 미들웨어로 사용 예
def token_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth_header = request.headers.get('Authorization')
        
        if not auth_header or not auth_header.startswith('Bearer '):
            return jsonify({'message': 'Authentication required'}), 401
        
        token = auth_header.split(' ')[1]
        user_data = verify_token(token)

        if not user_data:
            return jsonify({'message': 'Invalid token'}), 401
        
        request.user = user_data
        return f(*args, **kwargs)
    
    return decorated

# 라우트 예제
@app.route('/api/protected')
@token_required
def protected_route():
    return jsonify({'message': 'Access granted', 'user': request.user})

@app.route('/api/login', methods=['POST'])
def login():
    # 실제 구현에서는 데이터베이스에서 사용자 검증 필요
    user = {
        'id': 123,
        'name': 'Test User',
        'email': 'test@example.com',
        'roles': ['user']
    }
    
    token = generate_token(user)
    return jsonify({'token': token})

Java에서의 JWT 구현

jjwt 라이브러리를 사용한 예제:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

@Component
public class JwtUtil {

    private final Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    private final long JWT_TOKEN_VALIDITY = 60 * 60 * 1000; // 1시간

    // JWT 토큰에서 사용자 이름 추출
    public String extractUsername(String token) {
        return extractClaim(token, Claims::getSubject);
    }

    // JWT 토큰에서 만료 날짜 추출
    public Date extractExpiration(String token) {
        return extractClaim(token, Claims::getExpiration);
    }

    // JWT 토큰에서 클레임 추출
    public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
    }

    // 모든 클레임 추출
    private Claims extractAllClaims(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    // 토큰 만료 확인
    private Boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    // 사용자에 대한 JWT 토큰 생성
    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        return createToken(claims, userDetails.getUsername());
    }

    // JWT 토큰 생성
    private String createToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY))
                .signWith(key)
                .compact();
    }

    // JWT 토큰 검증
    public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = extractUsername(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }
}

8. JWT 관련 도구 및 라이브러리

JWT 작업을 위한 유용한 도구와 라이브러리

디버깅 및 검사 도구

  1. jwt.io:
    • JWT 디코딩, 검증, 생성을 위한 온라인 도구
    • 다양한 알고리즘 지원
    • 토큰 구조 시각화 제공
  2. JSON Web Token Debugger Chrome Extension:
    • 브라우저에서 직접 JWT 디코딩 및 검사
    • 개발 및 디버깅 시 유용
  3. JWT Validator:
    • JWT 검증 도구
    • 다양한 서명 알고리즘 지원

주요 JWT 라이브러리

다양한 프로그래밍 언어별 주요 JWT 라이브러리:

  1. JavaScript/Node.js:
    • jsonwebtoken: Node.js에서 가장 인기 있는 JWT 라이브러리
    • jose: 완전한 JSON Object Signing and Encryption 구현
  2. Python:
    • PyJWT: 가볍고 사용하기 쉬운 JWT 라이브러리
    • python-jose: JWS, JWE, JWK, JWA 구현 포함
  3. Java:
    • jjwt: 사용하기 쉬운 JWT 생성 및 검증
    • java-jwt: Auth0에서 제공하는 JWT 라이브러리
  4. C#/.NET:
  5. PHP:
  6. Ruby:
  7. Go:

JWT 관련 프레임워크 통합

많은 웹 프레임워크와 인증 시스템이 JWT를 지원:

  1. Spring Security (Java):
    • JWT 기반 인증 지원
    • OAuth2 및 JWT 통합
  2. Passport.js (Node.js):
  3. Django REST Framework (Python):
  4. ASP.NET Core (C#):
    • 내장 JWT 인증 미들웨어
    • 쉬운 설정 및 통합
  5. Laravel (PHP):

JWT와 관련 표준

JWT는 더 큰 JSON 객체 서명 및 암호화(JOSE) 프레임워크의 일부이다.

JOSE 프레임워크

JSON Object Signing and Encryption(JOSE) 프레임워크는 JSON 데이터 구조를 사용하여 보안 서비스를 제공하는 표준 모음:

  1. JWS(JSON Web Signature) - RFC 7515:
    • JSON 데이터 구조 서명을 위한 표준
    • 데이터 무결성과 출처 인증 제공
    • JWT의 서명 메커니즘 정의
  2. JWE(JSON Web Encryption) - RFC 7516:
    • JSON 데이터 구조 암호화를 위한 표준
    • 기밀성 제공
    • JWT의 암호화 메커니즘 정의
  3. JWK(JSON Web Key) - RFC 7517:
    • 암호화 키를 JSON 형식으로 표현하는 표준
    • 키 정보 교환에 사용
    • 공개 키 인프라(PKI)를 단순화
  4. JWA(JSON Web Algorithms) - RFC 7518:
    • JWS, JWE, JWK에서 사용되는 암호화 알고리즘 정의
    • 서명, 암호화, 키 암호화, 콘텐츠 암호화 등을 위한 알고리즘 지정

OpenID Connect와 JWT

JWT는 OpenID Connect(OIDC) 프로토콜의 핵심 구성 요소이다:

  1. ID 토큰:
    • OpenID Connect의 핵심 개념
    • 사용자 인증 정보를 포함하는 JWT
    • iss, sub, aud, exp, iat 등의 표준 클레임 포함
  2. UserInfo 응답:
    • 선택적으로 JWT 형식으로 제공 가능
    • 사용자 프로필 정보 포함
  3. 클라이언트 등록:
    • JWT를 사용한 클라이언트 인증 지원

OAuth 2.0과 JWT

JWT는 OAuth 2.0 프로토콜에서 여러 방식으로 활용된다:

  1. Bearer 토큰 형식:
    • JWT는 OAuth 2.0에서 액세스 토큰으로 사용 가능
    • RFC 6750에 정의된 Bearer 토큰 전송 방식 사용
  2. 클라이언트 인증:
    • JWT를 사용한 클라이언트 인증
    • RFC 7523에 정의된 JWT 프로필
  3. 토큰 교환:
    • JWT 교환을 위한 OAuth 2.0 확장(JWT Bearer Token Flow)
    • 한 도메인의 JWT를 다른 도메인에서 사용 가능한 토큰으로 교환

용어 정리

용어설명

참고 및 출처