From 1e6e783fcc90054f675e17379e96eff5448b0e01 Mon Sep 17 00:00:00 2001 From: iven Date: Tue, 28 Apr 2026 01:11:17 +0800 Subject: [PATCH] =?UTF-8?q?fix(server):=20=E5=81=A5=E5=BA=B7=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E5=92=8C=20OpenAPI=20=E7=AB=AF=E7=82=B9=E7=A7=BB?= =?UTF-8?q?=E5=87=BA=E9=99=90=E6=B5=81=E4=B8=AD=E9=97=B4=E4=BB=B6=E8=8C=83?= =?UTF-8?q?=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit account_lockout_middleware 改为 fail-close 后,/health 和 /docs/openapi.json 不应受影响。将它们提取为 unthrottled_routes 独立层。 --- crates/erp-server/src/main.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/crates/erp-server/src/main.rs b/crates/erp-server/src/main.rs index 522a819..d443af1 100644 --- a/crates/erp-server/src/main.rs +++ b/crates/erp-server/src/main.rs @@ -503,12 +503,7 @@ async fn main() -> anyhow::Result<()> { // Layer execution order (outer → inner): account_lockout → rate_limit_by_ip // So account lockout check runs FIRST, then IP rate limiting let public_routes = Router::new() - .merge(handlers::health::health_check_router()) .merge(erp_auth::AuthModule::public_routes()) - .route( - "/docs/openapi.json", - axum::routing::get(handlers::openapi::openapi_spec), - ) .layer(axum::middleware::from_fn_with_state( state.clone(), middleware::rate_limit::account_lockout_middleware, @@ -519,6 +514,15 @@ async fn main() -> anyhow::Result<()> { )) .with_state(state.clone()); + // Unthrottled public routes (health, docs) — no rate limiting + let unthrottled_routes = Router::new() + .merge(handlers::health::health_check_router()) + .route( + "/docs/openapi.json", + axum::routing::get(handlers::openapi::openapi_spec), + ) + .with_state(state.clone()); + // Clone jwt_secret for upload auth before protected_routes closure moves it let secret_for_uploads = jwt_secret.clone(); @@ -577,7 +581,7 @@ async fn main() -> anyhow::Result<()> { async move { upload_auth_middleware(secret, req, next).await } })); let app = Router::new() - .nest("/api/v1", public_routes.merge(protected_routes)) + .nest("/api/v1", unthrottled_routes.merge(public_routes).merge(protected_routes)) .nest("/uploads", uploads_router) .layer(cors);