增强JWT/token缓存:verify_token加入内存缓存(30秒TTL,最多1000条,自动清理过期),避免每次请求都重复HMAC验证和磁盘I/O;配合server-core的Redis缓存,全线性能优化
This commit is contained in:
+42
-21
@@ -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
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user