jwt --- JSON Web Token

面向 MicroPython 的 JSON Web Token(JWT)标准的小型实现。JWT 是一种紧凑的、URL 安全的容器,用于承载由签发者签名的 JSON 载荷,从而使验证者能够检测篡改和过期。

此 MicroPython 移植版本特意做得非常精简:

  • 仅支持 HS256(使用 SHA-256 的 HMAC)。RSA / ECDSA / EdDSA 算法未实现;签发者和验证者必须共享一个对称密钥。

  • 可选的 exp(过期)声明会被处理。其他注册声明(nbfiatissaudsubjti)会原样保留在载荷中传递,但不会被验证;应用程序如有需要可自行检查它们。

  • 不支持密钥轮换、JWKS 或受众列表处理。

函数

jwt.encode(payload: dict, key: bytes | str, algorithm: str = 'HS256') str

payload 编码为一个已签名的 JWT,并返回所得的紧凑序列化结果(形如 "header.payload.signature"str,每个段均经过 Base64-URL 编码)。

payload

一个可 JSON 序列化的声明字典。标准声明(expiatsub、...)会原样传递;允许使用自定义的应用程序键。

key

共享的 HMAC 密钥。首选 bytesstr 会自动以 UTF-8 编码。

algorithm

必须为 "HS256"(默认值)。其他任何值都会引发 exceptions.InvalidAlgorithmError

jwt.decode(token: str, key: bytes | str, algorithms: list = ['HS256']) dict

验证 token 的签名以及(如果存在)其 exp 声明,并返回解码后的载荷字典。任何失败都会引发 exceptions.PyJWTError 的子类——调用方通常捕获该基类。

token

encode()(或任何兼容的签发者)生成的紧凑 JWT 字符串。

key

共享的 HMAC 密钥。必须与编码时使用的密钥相匹配。

algorithms

调用方愿意接受的算法列表。其中必须包含 HS256,并且 token 头部的 alg 必须在该列表中。默认值为 ["HS256"]

引发:

异常

所有异常都嵌套在模块属性 jwt.exceptions 之下。

exception exceptions.PyJWTError

所有 JWT 失败的基类。如果你无需区分下面列出的各种情况,则捕获此类。

exception exceptions.InvalidTokenError

token 在结构上无效——段的数量不对、某个段无法通过 Base64 解码,或 JSON 无法解析。是 exceptions.PyJWTError 的子类。

exception exceptions.InvalidAlgorithmError

token 的算法不在调用方接受的列表中,或者调用方请求了 HS256 以外的算法。是 exceptions.PyJWTError 的子类。

exception exceptions.InvalidSignatureError

token 的签名与使用所提供密钥根据头部和载荷计算出的 HMAC 不匹配。是 exceptions.PyJWTError 的子类。

exception exceptions.ExpiredSignatureError

token 的 exp 声明已是过去时间。是 exceptions.PyJWTError 的子类。要使此检查有意义,必须设置摄像头的挂钟时间(通过 ntptime.settime())。

示例

一个对称密钥的签发/验证流程:

import jwt
import time

SECRET = b"keep-this-out-of-source-control"

payload = {
    "sub": "kitchen-cam",
    "role": "admin",
    "exp": time.time() + 3600,                 # 1 hour from now
}

token = jwt.encode(payload, SECRET)
print("token:", token)

try:
    claims = jwt.decode(token, SECRET)
except jwt.exceptions.PyJWTError as e:
    print("rejected:", type(e).__name__)
else:
    print("subject:", claims["sub"])

签名和验证使用相同的密钥,因此验证者必须持有签发者所使用的密钥。对于摄像头作为签发者的服务(向配对的手机分发 token),请将密钥保存在摄像头文件系统中,并像对待任何其他长期凭据一样对待它——参见 运维:密钥、过期与故障排查

备注

本模块依赖 hmachashlib,两者均已内置于摄像头中。无需任何外部配置。密钥可以是任意长度,但当密钥长度至少达到 SHA-256 的块大小(32 字节)时,HMAC 构造最为有用。