feat(server): BLE 网关独立限流 — 每网关 60 req/60s
为 /health/gateway 路由添加 gateway_id 级别的速率限制, 网关认证(API Key)→ 限流检查 → handler 三层中间件。 Redis 不可达时同样遵循 fail_close 策略。
This commit is contained in:
@@ -750,6 +750,10 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.nest(
|
.nest(
|
||||||
"/health/gateway",
|
"/health/gateway",
|
||||||
erp_health::HealthModule::gateway_routes()
|
erp_health::HealthModule::gateway_routes()
|
||||||
|
.layer(axum::middleware::from_fn_with_state(
|
||||||
|
state.clone(),
|
||||||
|
middleware::rate_limit::rate_limit_by_gateway,
|
||||||
|
))
|
||||||
.layer(axum::middleware::from_fn_with_state(
|
.layer(axum::middleware::from_fn_with_state(
|
||||||
state.clone(),
|
state.clone(),
|
||||||
erp_health::gateway_auth::gateway_auth_middleware,
|
erp_health::gateway_auth::gateway_auth_middleware,
|
||||||
|
|||||||
@@ -268,3 +268,34 @@ fn extract_client_ip(headers: &axum::http::HeaderMap) -> String {
|
|||||||
})
|
})
|
||||||
.unwrap_or_else(|| "unknown".to_string())
|
.unwrap_or_else(|| "unknown".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// BLE 网关级别的限流中间件。
|
||||||
|
///
|
||||||
|
/// 从 GatewayAuthContext 中读取 gateway_id 作为标识符。
|
||||||
|
/// 限制每个网关设备 60 req/60s。
|
||||||
|
/// 必须在 gateway_auth_middleware 之后挂载(需要认证上下文)。
|
||||||
|
pub async fn rate_limit_by_gateway(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
req: Request<Body>,
|
||||||
|
next: Next,
|
||||||
|
) -> Response {
|
||||||
|
let identifier = req
|
||||||
|
.extensions()
|
||||||
|
.get::<erp_health::gateway_auth::GatewayAuthContext>()
|
||||||
|
.map(|ctx| ctx.gateway_id.clone())
|
||||||
|
.unwrap_or_else(|| "unknown_gateway".to_string());
|
||||||
|
let fail_close = state.config.rate_limit.fail_close;
|
||||||
|
apply_rate_limit(
|
||||||
|
RateLimitParams {
|
||||||
|
redis_client: &state.redis,
|
||||||
|
fail_close,
|
||||||
|
max_requests: 60,
|
||||||
|
window_secs: 60,
|
||||||
|
prefix: "gateway",
|
||||||
|
},
|
||||||
|
&identifier,
|
||||||
|
req,
|
||||||
|
next,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user