以下是一个关于Nginx配置跨域资源共享(CORS)的详细示例,涵盖常见场景及安全实践:
一、基础CORS配置(允许所有源)
server {
listen 80;
server_name api.example.com;
location / {
# 简单请求头配置
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
# 处理预检请求(OPTIONS)
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Max-Age' 1728000; # 缓存20天
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://backend_service;
}
}
二、安全CORS配置(限制特定源)
server {
listen 80;
server_name api.example.com;
# 定义允许的源(支持通配符)
map $http_origin $cors_allowed_origin {
default '';
~^https?://(www\.)?example\.com(:[0-9]+)?$ $http_origin;
~^https?://(www\.)?trusted-partner\.com(:[0-9]+)?$ $http_origin;
}
location / {
# 动态设置允许的源
add_header 'Access-Control-Allow-Origin' $cors_allowed_origin;
add_header 'Access-Control-Allow-Credentials' 'true'; # 允许携带凭证
# 严格限制请求方法
add_header 'Access-Control-Allow-Methods' 'GET, POST';
# 限制请求头(根据实际需求调整)
add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization';
# 暴露响应头(给前端读取)
add_header 'Access-Control-Expose-Headers' 'X-Custom-Header';
# 预检请求处理
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $cors_allowed_origin;
add_header 'Access-Control-Allow-Methods' 'GET, POST';
add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization';
add_header 'Access-Control-Max-Age' 86400; # 缓存1天
return 204;
}
proxy_pass http://backend_service;
}
}
三、高级场景配置
1. 携带Cookie/认证信息
server {
listen 80;
server_name api.example.com;
location / {
add_header 'Access-Control-Allow-Origin' 'https://client.example.com';
add_header 'Access-Control-Allow-Credentials' 'true'; # 必须显式设置
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type';
# 预检请求处理
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://client.example.com';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type';
add_header 'Access-Control-Max-Age' 3600; # 缓存1小时
return 204;
}
proxy_pass http://backend_service;
}
}
2. 自定义响应头暴露
server {
listen 80;
server_name api.example.com;
location / {
add_header 'Access-Control-Allow-Origin' 'https://client.example.com';
add_header 'Access-Control-Expose-Headers' 'X-RateLimit-Limit,X-RateLimit-Remaining'; # 暴露自定义头
add_header 'Access-Control-Allow-Methods' 'GET';
add_header 'Access-Control-Allow-Headers' 'Accept';
proxy_pass http://backend_service;
}
}
四、安全加固建议
-
最小权限原则:
- 仅允许必要的HTTP方法(GET/POST等)
- 严格限制允许的请求头(避免使用
*通配符) - 精确匹配允许的源(避免使用泛域名)
-
缓存优化:
- 合理设置
Access-Control-Max-Age(建议1天以内) - 对静态资源设置长期缓存(需配合版本控制)
- 合理设置
-
日志监控:
log_format cors_log '{$remote_addr} - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_origin" "$http_access_control_request_headers"'; access_log /var/log/nginx/cors_access.log cors_log;
五、配置验证与测试
-
快速测试:
# 使用curl测试CORS配置 curl -I -X OPTIONS https://api.example.com/data \ -H "Origin: https://client.example.com" \ -H "Access-Control-Request-Method: GET" -
浏览器测试:
// 前端测试代码 fetch('https://api.example.com/data', { method: 'GET', credentials: 'include' // 测试携带凭证 }) .then(response => console.log(response.headers.get('X-Custom-Header'))) -
安全扫描:
# 使用核算工具检查CORS配置 nmap --script http-cors -p 80 api.example.com
六、常见问题排查
-
预检请求未缓存:
- 检查
Access-Control-Max-Age值是否合理 - 确认浏览器缓存策略(可通过开发者工具查看)
- 检查
-
凭证未携带:
- 确认
Access-Control-Allow-Credentials设置为true - 检查前端请求是否包含
credentials: 'include'
- 确认
-
源不匹配:
- 使用精确域名匹配(避免使用通配符
*) - 检查请求头中的
Origin值是否正确
- 使用精确域名匹配(避免使用通配符
该配置示例覆盖了CORS的核心场景,可根据实际需求扩展以下方向:
- 集成JWT验证(通过
auth_request模块) - 实现动态源白名单(通过Lua脚本)
- 添加速率限制(通过
limit_req模块) - 配置HTTPS强制跳转(通过
rewrite规则)
建议通过浏览器开发者工具的Network面板验证CORS配置,并结合安全扫描工具定期审计跨域策略。
1027

被折叠的 条评论
为什么被折叠?



