nginx反向代理中安全配置cors需精准限定作用范围、显式处理options预检、动态白名单匹配origin并禁用通配符与credentials组合,所有add_header须加always参数以防覆盖。

在 Nginx 反向代理中配置安全的 CORS 策略,核心不是“加几个头”,而是精准控制作用范围、正确响应预检、支持多源且不破坏凭证透传。关键在于把逻辑写对位置、用对指令、避开常见陷阱。
只在 API 路径下注入头,避免污染其他资源
CORS 响应头必须严格限定在被代理的接口路径内,不能放在 server 或根 location / 块里。否则静态文件、健康检查、favicon 等也会带上这些头,可能干扰监控或引发缓存异常。
- ✅ 正确写法:在
location /api/ { }这类明确代理后端的块中配置 - ⚠️ 注意
proxy_pass末尾斜杠:写成proxy_pass http://backend:8000/;会剥离/api前缀;写成proxy_pass http://backend:8000;则原样转发,路径匹配逻辑完全不同
显式拦截并快速响应 OPTIONS 预检请求
浏览器在发非简单请求前,必先发一个 OPTIONS 请求试探权限。Nginx 若不拦截,就会把请求转给后端——而多数后端根本不处理 OPTIONS,直接返回 404 或 502,导致跨域失败。
- 必须用
if ($request_method = 'OPTIONS') { ... return 204; } -
return 204不带响应体,符合规范;用return 200加空体容易因Content-Length不一致出问题 -
add_header在if块里不继承,所有头都要重复写一遍
用 map 构建动态 Origin 白名单,禁用通配符 + credentials 组合
一旦前端启用了 withCredentials: true(比如要传 Cookie 登录),Access-Control-Allow-Origin: * 就完全失效,浏览器会直接拒绝响应。必须动态比对请求头中的 Origin,只放行可信域名。
- 在
http块中定义白名单映射:
default "";
"~^http://localhost(:\d+)?$" "$http_origin";
"~^https://app\.yourcompany\.com$" "$http_origin";
"~^https://admin\.yourcompany\.com$" "$http_origin";
}
- 在
location中引用:add_header 'Access-Control-Allow-Origin' $cors_origin always; - 配合
add_header 'Access-Control-Allow-Credentials' 'true';才能支持登录态透传
确保响应头真正生效,绕过缓存与覆盖问题
Nginx 的 add_header 默认不作用于错误响应(如 401、500),且容易被上游服务返回的同名头覆盖,导致策略形同虚设。
- 所有
add_header都加上always参数,例如:add_header 'Access-Control-Allow-Origin' $cors_origin always; - 必须包含
Access-Control-Allow-Methods和Access-Control-Allow-Headers,明确声明允许的方法和自定义头 - 建议加上
Access-Control-Expose-Headers(如X-Request-ID)让前端能读取特定响应头











