From 988f6cd6a5f66b88adf4befc217fcf8aed2b05fe Mon Sep 17 00:00:00 2001 From: iven Date: Tue, 28 Apr 2026 11:23:53 +0800 Subject: [PATCH] =?UTF-8?q?fix(auth):=20JWT=20=E4=B8=AD=E9=97=B4=E4=BB=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20query=20parameter=20token=20=E5=9B=9E?= =?UTF-8?q?=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SSE/EventSource 无法设置自定义 Authorization 头,前端通过 ?token=xxx 传参。中间件现在优先读 Authorization 头,回退到 URL query parameter,修复 SSE 连接永远 401 的问题。 --- crates/erp-auth/src/middleware/jwt_auth.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/crates/erp-auth/src/middleware/jwt_auth.rs b/crates/erp-auth/src/middleware/jwt_auth.rs index 00a7c94..02ace73 100644 --- a/crates/erp-auth/src/middleware/jwt_auth.rs +++ b/crates/erp-auth/src/middleware/jwt_auth.rs @@ -39,18 +39,25 @@ pub async fn jwt_auth_middleware_fn( req: Request, next: Next, ) -> Result { - let auth_header = req + // 优先从 Authorization 头提取 token; + // 回退到 URL query parameter ?token=xxx(SSE/EventSource 无法设置自定义头) + let token = req .headers() .get("Authorization") .and_then(|v| v.to_str().ok()) - .ok_or(AppError::Unauthorized)?; - - let token = auth_header - .strip_prefix("Bearer ") + .and_then(|h| h.strip_prefix("Bearer ")) + .map(String::from) + .or_else(|| { + req.uri().query().and_then(|q| { + q.split('&') + .find_map(|pair| pair.strip_prefix("token=")) + .map(String::from) + }) + }) .ok_or(AppError::Unauthorized)?; let claims = - TokenService::decode_token(token, &jwt_secret).map_err(|_| AppError::Unauthorized)?; + TokenService::decode_token(&token, &jwt_secret).map_err(|_| AppError::Unauthorized)?; // Verify this is an access token, not a refresh token if claims.token_type != "access" {