TOC

关于 JWT 的看法

JWT 介绍

JSON Web Token

https://datatracker.ietf.org/doc/html/rfc7519

头 Headers + 负载 Payload + 签名 Signature

相关或者可能相关的 RFC:

  • RFC7515 JSON Web Signature (JWS) 签名
  • RFC7516 JSON Web Encryption (JWE) 加密
  • RFC7517 JSON Web Key (JWK) 密钥
  • RFC7518 JSON Web Algorithms (JWA) 算法
  • Rfc7519 JSON Web Token (JWT) 令牌
  • RFC7520 Examples of Protecting Content Using JSON Object Signing and Encryption (JOSE)
  • RFC7523 JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
  • RFC7538 JSON Web Key (JWK) Thumbprint
  • RFC7797 JSON Web Signature (JWS) Unencoded Payload Option
  • RFC7800 Proof-of-Possession Key Semantics for JSON Web Tokens (JWTs)
  • RFC8725 JSON Web Token Best Current Practices
  • RFC8812 CBOR Object Signing and Encryption (COSE) and JSON Object Signing and Encryption (JOSE) Registrations for Web Authentication (WebAuthn) Algorithms
  • RFC9101 The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)
  • RFC9118 Enhanced JSON Web Token (JWT) Claim Constraints for Secure Telephone Identity Revisited (STIR) Certificates

JSON 实现

import base64

def jsonify(obj):
    return json.dumps(obj, ensure_ascii=False, separators=',:')

def base64urlEncoding(s):
    return base64.urlsafe_b64encode(s).rstrip(b'=').decode('ascii')

def sign(key, msg):
    return base64urlEncoding(hmac.new(key, msg, hashlib.sha256).digest())

# def verify(key, msg, sig):
#     return key.verify(msg, base64.urlsafe_b64decode(sig))

def e(obj):
    return base64urlEncoding(jsonify(header).encode('utf-8'))

def encode(key, header, payload):
    s = e(header) + '.' + e(payload)
    return s + '.' + sign(key, s)

def decode(token):
    header_str, payload_str, sig = token.split('.')
    header = json.loads(base64.urlsafe_b64decode(header_str).decode('utf-8'))
    payload = json.loads(base64.urlsafe_b64decode(payload_str).decode('utf-8'))
    sig = base64.urlsafe_b64decode(sig)

header = {
  "alg": "HS256",
  "typ": "JWT"
}
payload = {
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

signature = HMAC_SHA256(
    secret,
    base64urlEncoding(header) + '.' +
    base64urlEncoding(payload)
)
const token = base64urlEncoding(header) + '.' + base64urlEncoding(payload) + '.' + base64urlEncoding(signature)

标准字段

Claim 字段

Code Name Description
iss Issuer ..
sub Subject ..
aud Audience ..
exp Expiration Time ..
nbf Not Before ..
iat Issued At ..
jti JWT ID ..

Header 字段

Code Name Description
typ Type ..
cty Content Type ..
alg Algorithm ..
kid Key ID ..
x5c X.509 Certificate ..
x5u X.509 URL ..
x5t X.509 Thumbprint ..
jku JSON Web Key URL ..
jwk JSON Web Key ..
x5t#S256 X.509 SHA-256 Thumbprint ..