JWT(JSON Web Token)는 인증 및 정보 교환을 위한 JSON 기반의 웹 토큰입니다. JWT는 두 가지 주요 암호화 방식을 사용하여 서명될 수 있습니다: 비대칭 암호화(RS256)과 대칭 암호화(HS256). 이 문서에서는 두 가지 암호화 방식의 차이점을 비교하고, 각각의 사용 예시를 제공합니다.
JWT는 세 부분으로 구성됩니다: Header, Payload, Signature(서명).

헤더는 토큰의 유형과 서명에 사용된 알고리즘 정보를 포함합니다. 일반적으로 다음과 같이 구성됩니다:
{
"alg": "RS256",
"typ": "JWT"
}
페이로드는 토큰의 클레임을 포함합니다. 클레임은 토큰에 담을 정보로, 사용자 정보나 토큰의 만료 시간 등이 포함될 수 있습니다. 페이로드의 정보는 JSON 형식으로 구성됩니다.
페이로드에 담기는 정보는 세 가지 유형으로 나뉩니다:
iss, 토큰 만료 시간 exp, 토큰 발급 시간 iat 등이 있습니다.{"https://example.com/is_admin": true}와 같은 형식입니다.{"username": "user1"}와 같은 형식입니다.페이로드 예시:
{
"iss": "example.com",
"exp": 1485270000000,
"https://example.com/is_admin": true,
"userId": "user1",
"username": "alex"
}
서명은 헤더와 페이로드를 인코딩한 후, 이를 비밀 키(대칭 암호화) 또는 개인 키(비대칭 암호화)로 해싱하여 생성합니다. 서명은 토큰의 무결성을 확인하는 데 사용됩니다.

sequenceDiagram
participant Client
participant Server
participant TokenManager
Client->>Server: 로그인 요청 username, password
Server->>TokenManager: 헤더 및 페이로드 생성
TokenManager->>TokenManager: 서명 생성 Private Key/Secret Key 사용
TokenManager->>Server: JWT 반환 헤더.페이로드.서명
Server->>Client: JWT 반환
Client->>Client: JWT 저장 local storage/cookies
비대칭 암호화는 RSA 알고리즘을 사용하여 두 개의 키 쌍(Private Key와 Public Key)을 사용합니다.

sequenceDiagram
participant Client
participant Server
participant TokenManager
Client->>Server: 로그인 요청 username, password
Server->>TokenManager: 자격 증명 확인 및 JWT 생성 Private Key로 서명
TokenManager->>Server: JWT 반환
Server->>Client: JWT 반환
Client->>Client: JWT 저장 local storage/cookies
Client->>Server: Authorization 헤더에 JWT 포함 요청
Server->>TokenManager: JWT 검증 Public Key로 서명 검증
TokenManager->>Server: 서명 유효 시 요청 처리
Server->>Client: 요청된 리소스 반환
import jwt
from datetime import datetime, timedelta
class TokenManager:
def __init__(self, private_key: str, public_key: str, access_token_expire_minutes: int, refresh_token_expire_days: int):
self.private_key = private_key
self.public_key = public_key
self.access_token_expire_minutes = access_token_expire_minutes
self.refresh_token_expire_days = refresh_token_expire_days
def generate_token(self, user: dict) -> str:
payload = {
"user_id": user["user_id"],
"exp": datetime.utcnow() + timedelta(minutes=self.access_token_expire_minutes),
"iat": datetime.utcnow()
}
token = jwt.encode(payload, self.private_key, algorithm="RS256")
return token
def verify_token(self, token: str) -> dict:
try:
payload = jwt.decode(token, self.public_key, algorithms=["RS256"])
return payload
except jwt.ExpiredSignatureError:
raise Exception("Token has expired")
except jwt.InvalidTokenError:
raise Exception("Invalid token")
대칭 암호화는 하나의 비밀 키(Secret Key)를 사용하여 토큰을 서명하고 검증합니다.

sequenceDiagram
participant Client
participant Server
participant TokenManager
Client->>Server: 로그인 요청 username, password
Server->>TokenManager: 자격 증명 확인 및 JWT 생성 Secret Key로 서명
TokenManager->>Server: JWT 반환
Server->>Client: JWT 반환
Client->>Client: JWT 저장 local storage/cookies
Client->>Server: Authorization 헤더에 JWT 포함 요청
Server->>TokenManager: JWT 검증 Secret Key로 서명 검증
TokenManager->>Server: 서명 유효 시 요청 처리
Server->>Client: 요청된 리소스 반환
import jwt
from datetime import datetime, timedelta
class TokenManager:
def __init__(self, secret_key: str, access_token_expire_minutes: int, refresh_token_expire_days: int):
self.secret_key = secret_key
self.access_token_expire_minutes = access_token_expire_minutes
self.refresh_token_expire_days = refresh_token_expire_days
def generate_token(self, user: dict) -> str:
payload = {
"user_id": user["user_id"],
"exp": datetime.utcnow() + timedelta(minutes=self.access_token_expire_minutes),
"iat": datetime.utcnow()
}
token = jwt.encode(payload, self.secret_key, algorithm="HS256")
return token
def verify_token(self, token: str) -> dict:
try:
payload = jwt.decode(token, self.secret_key, algorithms=["HS256"])
return payload
except jwt.ExpiredSignatureError:
raise Exception("Token has expired")
except jwt.InvalidTokenError:
raise Exception("Invalid token")
JWT는 일반적으로 두 가지 유형의 토큰으로 사용됩니다: Access Token과 Refresh Token.
Access Token은 사용자가 인증된 후, 특정 리소스에 접근하기 위해 사용하는 토큰입니다. 일반적으로 수명이 짧고, 만료 시간이 설정되어 있어 만료 후에는 재발급 받아야 합니다. Access Token은 클라이언트가 서버에 요청을 보낼 때마다 포함되어야 합니다.
Refresh Token은 Access Token이 만료된 후, 새로운 Access Token을 발급받기 위해 사용하는 토큰입니다. Refresh Token은 수명이 더 길고, 주로 클라이언트의 보안 강화를 위해 사용됩니다. Refresh Token을 통해 새로운 Access Token을 발급받을 수 있습니다.

sequenceDiagram
participant Client
participant Server
participant TokenManager
Client->>Server: 로그인 요청 username, password
Server->>TokenManager: Access Token 및 Refresh Token 생성 Secret Key로 서명
TokenManager->>Server: Access Token 및 Refresh Token 반환
Server->>Client: Access Token 및 Refresh Token 반환
Client->>Client: Access Token 및 Refresh Token 저장 local storage/cookies
Client->>Server: Authorization 헤더에 Access Token 포함 요청
Server->>TokenManager: Access Token 검증 Secret Key로 서명 검증
TokenManager->>Server: 서명 유효 시 요청 처리
Server->>Client: 요청된 리소스 반환
Client->>Server: Access Token 만료 시 Refresh Token으로 새로운 Access Token 요청
Server->>TokenManager: Refresh Token 검증 Secret Key로 서명 검증
TokenManager->>Server: 새로운 Access Token 반환
Server->>Client: 새로운 Access Token 반환
Client->>Client: 새로운 Access Token 저장 local storage/cookies
비대칭 암호화(RS256)와 대칭 암호화(HS256)는 각각 장단점이 있습니다.
JWT 암호화 방식을 선택할 때는 보안 요구 사항과 시스템 구조를 고려해야 합니다.