From c4a2f2f9c61ffcfb6180bc02acfe09f731f8b93e Mon Sep 17 00:00:00 2001 From: Pine Date: Sat, 5 Sep 2026 14:35:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=BC=BAJWT/token=E7=BC=93=E5=AD=98?= =?UTF-8?q?=EF=BC=9Averify=5Ftoken=E5=8A=A0=E5=85=A5=E5=86=85=E5=AD=98?= =?UTF-8?q?=E7=BC=93=E5=AD=98(30=E7=A7=92TTL=EF=BC=8C=E6=9C=80=E5=A4=9A100?= =?UTF-8?q?0=E6=9D=A1=EF=BC=8C=E8=87=AA=E5=8A=A8=E6=B8=85=E7=90=86?= =?UTF-8?q?=E8=BF=87=E6=9C=9F)=EF=BC=8C=E9=81=BF=E5=85=8D=E6=AF=8F?= =?UTF-8?q?=E6=AC=A1=E8=AF=B7=E6=B1=82=E9=83=BD=E9=87=8D=E5=A4=8DHMAC?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E5=92=8C=E7=A3=81=E7=9B=98I/O=EF=BC=9B?= =?UTF-8?q?=E9=85=8D=E5=90=88server-core=E7=9A=84Redis=E7=BC=93=E5=AD=98?= =?UTF-8?q?=EF=BC=8C=E5=85=A8=E7=BA=BF=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pineagents/app/auth.py | 63 +++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/src/pineagents/app/auth.py b/src/pineagents/app/auth.py index a11c3c5..2da469a 100644 --- a/src/pineagents/app/auth.py +++ b/src/pineagents/app/auth.py @@ -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 # ---------------------------------------------------------------------------