问题
当前后端已挂载 CORSMiddleware,但受保护接口的跨域预检请求仍会被 AuthMiddleware 提前拦截。
浏览器发送预检 OPTIONS 时不会携带 Bearer token。后端因此返回 HTTP 200 + 业务码 401,且响应缺少 access-control-allow-* 头,浏览器不会继续发送实际的 GET、PATCH 或 POST 请求。
这会阻断所有前后端分域部署下的受保护接口,不只影响账号中心。
复现证据
在最新 main(efd230e)配置:
WINDUP_CORS_ORIGINS=https://frontend.example
实际中间件顺序:
RateLimitMiddleware → AuthMiddleware → CORSMiddleware
| Preflight |
Result |
POST /auth/login |
正常返回 OK,包含允许来源、方法和请求头 |
GET /auth/me |
返回业务码 401,缺少全部 CORS 响应头 |
PATCH /auth/profile |
返回业务码 401,缺少全部 CORS 响应头 |
POST /auth/change-password |
返回业务码 401,缺少全部 CORS 响应头 |
GET /projects |
返回业务码 401,缺少全部 CORS 响应头 |
根因
create_app() 先注册 CORSMiddleware,随后注册 AuthMiddleware 与 RateLimitMiddleware。按当前 Starlette 中间件装配顺序,后注册的中间件先收到请求,因此鉴权发生在 CORS 之前。
AuthMiddleware 只按路径白名单放行请求,没有单独放行 OPTIONS。受保护路径的预检没有 Authorization header,于是在到达 CORS 中间件前被返回“未登录”。
该顺序随 #149 的认证中间件注册进入主线。#139 处理的是“完全未挂 CORS”,#143 处理的是另一分支上的来源配置问题,均未覆盖受保护路径的预检顺序。
预期行为
- 已配置来源发出的合法预检请求应由 CORS 层处理,不要求 Bearer token。
- 预检成功后,实际受保护请求仍必须通过现有 JWT 鉴权。
- 未配置的来源不得获得
access-control-allow-origin。
- 公共认证接口行为保持不变。
验收标准
Scope
- 本 Issue 只修复 CORS 与鉴权中间件的请求顺序或预检放行逻辑,并补充测试。
- 不调整 JWT、业务权限、允许来源策略或前端账号中心代码。
Related Issues
Refs #139
Refs #143
Refs #149
Refs #161
Refs #183
问题
当前后端已挂载
CORSMiddleware,但受保护接口的跨域预检请求仍会被AuthMiddleware提前拦截。浏览器发送预检
OPTIONS时不会携带 Bearer token。后端因此返回 HTTP 200 + 业务码 401,且响应缺少access-control-allow-*头,浏览器不会继续发送实际的 GET、PATCH 或 POST 请求。这会阻断所有前后端分域部署下的受保护接口,不只影响账号中心。
复现证据
在最新
main(efd230e)配置:WINDUP_CORS_ORIGINS=https://frontend.example实际中间件顺序:
RateLimitMiddleware → AuthMiddleware → CORSMiddlewarePOST /auth/loginOK,包含允许来源、方法和请求头GET /auth/mePATCH /auth/profilePOST /auth/change-passwordGET /projects根因
create_app()先注册CORSMiddleware,随后注册AuthMiddleware与RateLimitMiddleware。按当前 Starlette 中间件装配顺序,后注册的中间件先收到请求,因此鉴权发生在 CORS 之前。AuthMiddleware只按路径白名单放行请求,没有单独放行OPTIONS。受保护路径的预检没有 Authorization header,于是在到达 CORS 中间件前被返回“未登录”。该顺序随 #149 的认证中间件注册进入主线。#139 处理的是“完全未挂 CORS”,#143 处理的是另一分支上的来源配置问题,均未覆盖受保护路径的预检顺序。
预期行为
access-control-allow-origin。验收标准
GET、PATCH、POST类型的受保护接口预检均能正常返回 CORS 响应头。/auth/me、/auth/profile、/auth/change-password和/projects。Scope
Related Issues
Refs #139
Refs #143
Refs #149
Refs #161
Refs #183