PyJWT (Python)JWT 库
错误信息
Not enough segments
也可能输出为
- jwt.exceptions.DecodeError: Not enough segments
PyJWT (Python) — jwt.exceptions.DecodeError
含义
PyJWT 无法把输入拆分为 `header.payload.signature`:其中的点少于两个。这个字符串不是紧凑序列化的 JWS,因此还没有用到任何密钥或算法。到达 `jwt.decode()` 的值不是 JWT——或者是在传递途中丢了尾部的 JWT。
原因
不透明的访问令牌,而不是 JWT
常见许多 OAuth 提供商签发的是不透明的访问令牌(Google 的 `ya29.…`、GitHub 的 `gho_…`)。这类令牌应由提供商通过内省或 userinfo 来验证,而不是拿来解码。只有 OpenID Connect 的 `id_token` 一定是 JWT。
解码了错误的变量
常见会话 ID、API 密钥、`str(None)`,或者前端传来的字面量“undefined”。在解码之前记录 `repr(token)[:40]`,通常就能查明原因。
令牌被截断了
偶见过短的数据库列、日志行长度限制,或者手动复制时没有复制完整,都可能丢掉最后一段及其前面的点。
修复方法
- 1.
解码前先检查格式
紧凑序列化的 JWS 恰好包含两个点。在 API 的入口处用 401 拒绝其他任何输入,这样格式错误的输入就永远不会到达解码器。
python def bearer_token(headers: dict) -> str | None: scheme, _, token = headers.get("Authorization", "").partition(" ") if scheme.lower() != "bearer" or token.count(".") != 2: return None # not a compact JWS: answer 401 instead of decoding return token - 2.
交由颁发者验证不透明令牌
如果提供商签发的是不透明访问令牌,就调用它的令牌内省端点(RFC 7662),或者配置提供商为你的 API 签发 JWT 格式的访问令牌(通常通过请求指定受众来实现)。
python import requests # Opaque tokens are validated by the authorization server (RFC 7662), not by decoding them. resp = requests.post( "https://issuer.example.com/oauth2/introspect", data={"token": token}, auth=(CLIENT_ID, CLIENT_SECRET), timeout=5, ) active = resp.json().get("active", False)