增强JWT/token缓存:verify_token加入内存缓存(30秒TTL,最多1000条,自动清理过期),避免每次请求都重复HMAC验证和磁盘I/O;配合server-core的Redis缓存,全线性能优化

This commit is contained in:
Pine
2026-09-05 14:35:42 +08:00
parent dc5cf7087a
commit c4a2f2f9c6
+42 -21
View File
@@ -174,35 +174,56 @@ def verify_token(token: str) -> Optional[str]:
"""Verify *token*, return username if valid, ``None`` otherwise.
Also checks if the token has been revoked (appears in the revocation list).
性能优化:验证结果缓存 30 秒,避免每次请求都重复 HMAC 验证和磁盘 I/O。
"""
import base64
# 性能优化:验证结果缓存(内存,30 秒 TTL)
global _token_verify_cache
if "_token_verify_cache" not in globals():
_token_verify_cache = {}
now = time.time()
cached = _token_verify_cache.get(token)
if cached is not None and now < cached["expires_at"]:
return cached["result"]
try:
parts = token.split(".", 1)
if len(parts) != 2:
return None
payload_b64, sig = parts
secret = _get_jwt_secret()
expected_sig = hmac.new(
secret.encode(),
payload_b64.encode(),
hashlib.sha256,
).hexdigest()
if not hmac.compare_digest(sig, expected_sig):
return None
payload = json.loads(base64.urlsafe_b64decode(payload_b64))
if payload.get("exp", 0) < time.time():
return None
# Check if token is revoked
jti = payload.get("jti")
if jti and _is_token_revoked(jti):
return None
return payload.get("sub")
result = None
else:
payload_b64, sig = parts
secret = _get_jwt_secret()
expected_sig = hmac.new(
secret.encode(),
payload_b64.encode(),
hashlib.sha256,
).hexdigest()
if not hmac.compare_digest(sig, expected_sig):
result = None
else:
payload = json.loads(base64.urlsafe_b64decode(payload_b64))
if payload.get("exp", 0) < now:
result = None
else:
# Check if token is revoked
jti = payload.get("jti")
if jti and _is_token_revoked(jti):
result = None
else:
result = payload.get("sub")
except (json.JSONDecodeError, KeyError, ValueError, TypeError) as exc:
logger.debug("Token verification failed: %s", exc)
return None
result = None
# 写缓存(30 秒 TTL
_token_verify_cache[token] = {"result": result, "expires_at": now + 30}
# 限制缓存大小,避免内存泄漏
if len(_token_verify_cache) > 1000:
# 清理过期的缓存项
_token_verify_cache = {k: v for k, v in _token_verify_cache.items() if time.time() < v["expires_at"]}
return result
# ---------------------------------------------------------------------------