페이지

2024년 11월 16일 토요일

JWT 토큰 생성과 유효성 확인 과정

JWT 토큰 생성과 유효성 확인 과정

API 서비스를 개발하고 이에 대한 접근 권한을 제어하기 위하여 JSON Web Token(JWT)을 활용할 수 있습니다. 이 문서에서는 JWT 토큰의 생성과 유효성 확인 과정을 그림과 Python 코드를 사용하여 설명합니다. 전자서명 알고리즘으로는 HS256을 사용하였습니다.

  • HS256(HMAC-SHA256)
    • 대칭키 암호화 방식
  • HMAC(Hash-based Message Authentication Code)
    • 해시 함수를 기반으로 메시지 인증 코드를 생성하는 알고리즘

다음은 토큰 생성과 유효성 확인 과정에서 사용하게 될 Base64 인코딩/디코딩 함수입니다.

import base64
import hashlib
import hmac

def base64_encode(input_as_bytes):
    b = base64.urlsafe_b64encode(input_as_bytes).decode('utf-8')
    return b.rstrip('=')

def base64_decode(input_as_string):
    padding = 4 - len(input_as_string) % 4
    input_as_string = input_as_string + '=' * padding
    return base64.urlsafe_b64decode(input_as_string.encode('utf-8')).decode('utf-8')

1. 토큰 생성

1.1. 다이어그램

1.2. Python 구현

def create_jwt_token(header_obj_str, payload_obj_str, secret):
    header = base64_encode(header_obj_str.encode('utf-8'))
    payload = base64_encode(payload_obj_str.encode('utf-8'))
    header_plus_payload = f'{header}.{payload}'
    
    m = hmac.new(secret.encode('utf-8'), digestmod=hashlib.sha256)
    m.update(header_plus_payload.encode('utf-8'))
    d = m.digest()
    signature = base64_encode(d)
    print('** Signature (algorithm: HS256) **')
    print(f'Byte size: {len(d)}')
    print(f'Base64 encoded: {signature}')

    jwt_token = f'{header_plus_payload}.{signature}'
    return jwt_token

header_obj_str = '{\
"typ":"JWT",\
"alg":"HS256"\
}'

payload_obj_str = '{\
"iss":"fun-with-jwts",\
"sub":"AzureDiamond",\
"jti":"f6c1097f-cc48-4949-a627-8b94fc5e37ba",\
"iat":1596185001,\
"exp":1596185061\
}'

secret = 'my-secret'

jwt_token = create_jwt_token(header_obj_str, payload_obj_str, secret)
print('** JWT token (structure: header.payload.signature) **')
print(jwt_token)

실행 결과:

** Signature (algorithm: HS256) **
Byte size: 32
Base64 encoded: UXvXY97CNcHv7LobrBagePBPeGiW2F-Z-nuINSmUy5k
** JWT token (structure: header.payload.signature) **
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmdW4td2l0aC1qd3RzIiwic3ViIjoiQXp1cmVEaWFtb25kIiwianRpIjoiZjZjMTA5N2YtY2M0OC00OTQ5LWE2MjctOGI5NGZjNWUzN2JhIiwiaWF0IjoxNTk2MTg1MDAxLCJleHAiOjE1OTYxODUwNjF9.UXvXY97CNcHv7LobrBagePBPeGiW2F-Z-nuINSmUy5k

입력

  • header object

    {
        "typ": "JWT",
        "alg": "HS256"
    }
    
  • payload object

    {
        "iss": "fun-with-jwts",
        "sub": "AzureDiamond",
        "jti": "f6c1097f-cc48-4949-a627-8b94fc5e37ba",
        "iat": 1596185001,
        "exp": 1596185061
    }
    
  • secret

    my-secret
    

출력

  • token

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmdW4td2l0aC1qd3RzIiwic3ViIjoiQXp1cmVEaWFtb25kIiwianRpIjoiZjZjMTA5N2YtY2M0OC00OTQ5LWE2MjctOGI5NGZjNWUzN2JhIiwiaWF0IjoxNTk2MTg1MDAxLCJleHAiOjE1OTYxODUwNjF9.UXvXY97CNcHv7LobrBagePBPeGiW2F-Z-nuINSmUy5k
    

2. 토큰 유효성 확인

2.1. 다이어그램

2.2. Python 구현

def validate_jwt_token(token, secret):
    pos = token.rfind('.')
    header_plus_payload = token[:pos]
    signature = token[pos+1:]
    
    m = hmac.new(secret.encode('utf-8'), digestmod=hashlib.sha256)
    m.update(header_plus_payload.encode('utf-8'))
    d = m.digest()
    
    signature_derived = base64_encode(d)
    
    return signature_derived == signature

token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmdW4td2l0aC1qd3RzIiwic3ViIjoiQXp1cmVEaWFtb25kIiwianRpIjoiZjZjMTA5N2YtY2M0OC00OTQ5LWE2MjctOGI5NGZjNWUzN2JhIiwiaWF0IjoxNTk2MTg1MDAxLCJleHAiOjE1OTYxODUwNjF9.UXvXY97CNcHv7LobrBagePBPeGiW2F-Z-nuINSmUy5k'
secret = 'my-secret'

is_valid = validate_jwt_token(token, secret)
print(f'** is_valid: {is_valid} **')

실행 결과:

** is_valid: True **

입력

  • token

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmdW4td2l0aC1qd3RzIiwic3ViIjoiQXp1cmVEaWFtb25kIiwianRpIjoiZjZjMTA5N2YtY2M0OC00OTQ5LWE2MjctOGI5NGZjNWUzN2JhIiwiaWF0IjoxNTk2MTg1MDAxLCJleHAiOjE1OTYxODUwNjF9.UXvXY97CNcHv7LobrBagePBPeGiW2F-Z-nuINSmUy5k
    
  • secret

    my-secret
    

출력

  • is_valid

    True
    

Written with StackEdit.

댓글 없음:

댓글 쓰기

Llama 3.2로 문장 생성 및 챗팅 완성 실습

Llama 3.2로 문장 생성 및 챗팅 완성 실습 Running Meta Llama on Linux 문서의 내용을 참고하여 Llama 3.2 1B 모델로 다음 두 가지 기능을 실습합니다. 문장 완성 챗팅 ...