Преглед изворни кода

fix: require client signature on all authenticated endpoints

nonvioce пре 3 месеци
родитељ
комит
d34d2a2c4e
1 измењених фајлова са 21 додато и 18 уклоњено
  1. 21 18
      tiku-server/app/routers/auth.py

+ 21 - 18
tiku-server/app/routers/auth.py

@@ -20,28 +20,31 @@ def verify_token(request: Request, credentials: HTTPAuthorizationCredentials | N
     if credentials.credentials != config.token:
         raise HTTPException(status_code=401, detail={"error": {"code": "unauthorized", "message": "Token 无效"}})
 
-    # 客户端请求签名验证(防止浏览器/curl直接调用)
+    # 客户端请求签名验证(所有认证请求必须带签名)
     req_ts = request.headers.get("X-Timestamp", "")
     req_sig = request.headers.get("X-Signature", "")
-    if req_ts and req_sig:
-        try:
-            ts = int(req_ts)
-            if abs(time.time() - ts) > 300:  # 5分钟窗口防重放
-                raise HTTPException(status_code=401, detail={
-                    "error": {"code": "timestamp_expired", "message": "请求时间戳过期"}
-                })
-            path = request.url.path
-            expected = hmac.new(
-                config.token.encode(), f"{request.method}{path}{req_ts}".encode(), hashlib.sha256
-            ).hexdigest()
-            if not hmac.compare_digest(expected, req_sig):
-                raise HTTPException(status_code=403, detail={
-                    "error": {"code": "invalid_signature", "message": "客户端签名无效"}
-                })
-        except (ValueError, TypeError):
+    if not req_ts or not req_sig:
+        raise HTTPException(status_code=403, detail={
+            "error": {"code": "missing_signature", "message": "缺少客户端签名,请使用 Flutter 客户端访问"}
+        })
+    try:
+        ts = int(req_ts)
+        if abs(time.time() - ts) > 300:
             raise HTTPException(status_code=401, detail={
-                "error": {"code": "bad_timestamp", "message": "时间戳格式错误"}
+                "error": {"code": "timestamp_expired", "message": "请求时间戳过期"}
             })
+        path = request.url.path
+        expected = hmac.new(
+            config.token.encode(), f"{request.method}{path}{req_ts}".encode(), hashlib.sha256
+        ).hexdigest()
+        if not hmac.compare_digest(expected, req_sig):
+            raise HTTPException(status_code=403, detail={
+                "error": {"code": "invalid_signature", "message": "客户端签名无效"}
+            })
+    except (ValueError, TypeError):
+        raise HTTPException(status_code=401, detail={
+            "error": {"code": "bad_timestamp", "message": "时间戳格式错误"}
+        })
 
     return True