必须使用动态白名单而非通配符:通过map指令匹配可信第三方域名,精确设置access-control-allow-origin;启用凭据时禁止*,预检请求用if拦截返回204,并显式声明方法、头字段与暴露头,后端需二次校验。

要让管理后台安全地接收来自第三方域名的跨域请求,关键不是“开放所有”,而是精准控制——只允许可信来源、限定必要方法与头字段,并明确处理凭据和预检逻辑。Nginx 本身不校验业务身份,但可通过响应头组合实现最小权限原则下的安全跨域。
明确允许指定第三方域名
避免使用 *(尤其当启用凭据时),改用静态白名单或动态匹配:
- 若第三方域名固定(如
https://admin.partner.com),直接写死:add_header 'Access-Control-Allow-Origin' 'https://admin.partner.com' always; - 若需支持多个域名(如合作伙伴 A/B/C),用
map指令做源验证:map $http_origin $cors_origin {<br> default "";<br> "https://admin.partner-a.com" $http_origin;<br> "https://admin.partner-b.com" $http_origin;<br>}
再在 location 中:add_header 'Access-Control-Allow-Origin' $cors_origin always; - 注意:
$http_origin是客户端真实发起请求的 Origin,Nginx 不伪造也不信任它,仅作匹配依据
限制跨域行为范围
缩小攻击面,只放行必需项:
-
方法:只开放管理后台实际需要的 HTTP 方法,例如:
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
禁用PATCH或CONNECT等非常规方法 -
请求头:仅声明前端真正携带的自定义头,例如:
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Partner-ID, X-Request-Timestamp' always;
不泛填*或冗余字段(如User-Agent通常无需显式允许) -
暴露头:仅暴露前端 JS 需读取的响应头,例如:
add_header 'Access-Control-Expose-Headers' 'X-Total-Count, X-RateLimit-Remaining' always;
凭据与预检的安全处理
管理后台常涉及登录态(Cookie / Token),必须谨慎配置凭据支持:
- 启用凭据需同时满足两点:
–add_header 'Access-Control-Allow-Credentials' 'true' always;
–Access-Control-Allow-Origin不能为*(必须是具体域名) - 必须显式处理
OPTIONS预检请求:
在 location 块中添加:if ($request_method = 'OPTIONS') {<br> add_header 'Access-Control-Allow-Origin' $cors_origin;<br> add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';<br> add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Partner-ID';<br> add_header 'Access-Control-Allow-Credentials' 'true';<br> add_header 'Access-Control-Max-Age' 86400;<br> add_header 'Content-Length' 0;<br> return 204;<br>} - 确保预检响应头与主请求响应头一致(特别是 Origin 和 Credentials),否则浏览器会拒绝后续实际请求
配合后端做二次校验(推荐)
Nginx 层仅做协议级放行,业务级安全需后端兜底:
- 在 Nginx 的
proxy_pass前,可添加proxy_set_header X-Forwarded-For $remote_addr;和X-Forwarded-Origin $http_origin;,供后端读取并做 IP 白名单、Origin 签名校验等 - 对敏感操作(如删除、权限变更),要求第三方在请求头中携带签名(如
X-Signature: hmac-sha256...),由后端验证,Nginx 不参与计算但透传 - 避免在 Nginx 中硬编码密钥或做复杂鉴权——那是后端职责











