JSON Web Token 包含用点(".")分隔的三部分:
形如:
xxxxxxxxxxxxxxx.yyyyy.zzzzzHeader 通常包含两部分:
下面是一个例子:
xxxxxxxxxx{ "alg": "HS256", "typ": "JWT"}使用 Base64Url 对 Header 进行编码,形成 JWT 的第一部分。
JWT 的第二部分是 Payload。它包含声明,声明是关于实体(实体通常是用户)和可选元数据的一系列语句。有三种类型的声明:预留的、公有的、私有的。
预留的声明: 预留的声明是一组预定义的声明。不强制,但是推荐使用它们。预留的声明(名称长度都是 3)包括:
iss(issuer):请求的发起人exp(expiration time):以秒为单位的过期时间sub (subject):主题aud (audience):参与者公有的声明: 使用公有的声明时应避免名称冲突
私有的声明: 私有的声明是自定义的声明,用于在系统的各部分间共享信息
下面是一个例子:
xxxxxxxxxx{ "sub": "1234567890", "name": "John Doe", "admin": true}使用 Base64Url 对 Payload 进行编码,形成 JWT 的第二部分。
签名部分使用编码后的 Header、编码后的 Payload、密钥以及** Header 中指定的算法**生成。
假如算法是 HMAC SHA256,那么签名的计算方式是:
xxxxxxxxxxHMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
签名用于核实 JWT 的发送者,确保消息没有被篡改。
JWT 包含三个用点分隔的 Base64 字符串。
下面是一个示例 JWT:

依赖包:
代码:
xxxxxxxxxximport timefrom typing import Tuple, Dict, Any
import jwtimport Crypto.PublicKey.RSA as RSA
def generate_rsa_keys(bits: int = 2048) -> Tuple[bytes, bytes]: # 随机生成 RSA key key: RSA.RsaKey = RSA.generate(bits) # 编码后的私钥 private_pem: bytes = key.exportKey() # 编码后的公钥 public_pem: bytes = key.publickey().exportKey() return private_pem, public_pem
def client_side(payload: Dict[str, Any], private_key: bytes) -> str: return jwt.encode(payload, private_key, "RS256")
def server_side(token: str, public_key: bytes) -> Dict[str, Any]: return jwt.decode(token, public_key, "RS256")
def test() -> None: private_key, public_key = generate_rsa_keys() # type: bytes, bytes payload: Dict[str, Any] = { "user_id": 1, "exp": time.time() + 100 } token: str = client_side(payload, private_key) print(token) decoded_payload: Dict[str, Any] = server_side(token, public_key) print(decoded_payload)
if __name__ == "__main__": test()重放攻击(Replay Attacks)又称重播攻击、回放攻击或新鲜性攻击(Freshness Attacks),是指攻击者发送目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。
jti 是被放到 JWT 中的唯一 ID,可以防止重放攻击。