Python使用JWT库时如何提取已过期JWT令牌的payload内容
问题根因
PyJWT的jwt.decode()方法默认开启全量校验(包含签名合法性、令牌过期时间校验等),你当前代码中令牌一旦过期,jwt.decode()会直接抛出jwt.ExpiredSignatureError异常,此时存储payload的data变量尚未完成赋值,异常捕获分支调用data["sub"]["username"]自然会触发报错。
另外你现有代码还存在逻辑漏洞:空token判断分支中仍然调用了jwt.decode(token, secretKey, algorithms=algorithm),token为空时该行会直接抛出异常,和你预期抛出"Token is missing"的逻辑不符。
修复方案
你可以通过jwt.decode()的options参数跳过指定校验项,先拿到payload再做后续校验逻辑,修改后的代码如下:
import jwt from flask import request from functools import wraps from werkzeug.exceptions import Forbidden, Unauthorized def admin_rights_required(f): @wraps(f) def _decorated(*args, **kwargs): config = readConfig() secretKey = config["JWT_SECRET_KEY"] algorithm = config["JWT_ENCODING_ALGORITHM"] token = None payload = None if "Authorization" in request.headers: auth_header = request.headers["Authorization"] token = auth_header.replace("Bearer ", "") # 先处理空token场景 if not token: raise Unauthorized("Token is missing") try: # 先跳过过期校验拿到payload,确保后续异常分支可访问用户信息 payload = jwt.decode(token, secretKey, algorithms=algorithm, options={"verify_exp": False}) # 再做正常全量校验(包含过期校验) jwt.decode(token, secretKey, algorithms=algorithm) if not _ruleUserObj.getRuleUserFromToken(token): raise jwt.InvalidTokenError if getTokenDurationDifference(token) == -1: raise jwt.InvalidTokenError currentUser = _ruleUserObj.getRuleUser(payload["sub"]["username"]) if not len(currentUser) > 0: raise jwt.InvalidTokenError if currentUser["isAdmin"] == False: raise Forbidden() except jwt.ExpiredSignatureError: # 此时payload已经提前赋值,可以正常访问 _ruleUserObj.updatedRuleUserSessionRemToken(payload["sub"]["username"]) raise Unauthorized("Signature expired. Please log in again.") except jwt.InvalidTokenError: # 合法签名的无效token才需要清理会话,非法签名的token payload不可信可以跳过 if payload and "sub" in payload and "username" in payload["sub"]: _ruleUserObj.updatedRuleUserSessionRemToken(payload["sub"]["username"]) raise Unauthorized("Invalid token. Please log in again.") return f(*args, **kwargs) return _decorated
核心修改点说明
- 提前通过
options={"verify_exp": False}跳过过期校验拿到payload,确保所有异常分支都能访问到有效签名令牌的用户信息 - 修复了空token场景下的逻辑错误,空token直接返回对应提示,不会触发无效解码
- 对InvalidTokenError分支增加了payload合法性判断,避免被伪造的无效令牌触发代码报错
内容的提问来源于stack exchange,提问作者SUNEEL KAUSHIK S
相关产品推荐
相关产品推荐

