
跨域资源共享(CORS)是一种安全机制,允许网页从不同域名加载资源。在Web开发中,CORS配置尤为重要,特别是在以下场景中:
1、前后端分离架构:前端应用部署在 frontend.example.com ,后端API服务运行在 api.example.com。
2、单页面应用(SPA):使用React、Vue或Angular等框架开发的应用程序需要访问不同域名的API。
3、第三方服务集成:集成社交媒体登录、地图服务或支付网关等第三方API。
4、微服务架构:多个服务部署在不同子域下,需要相互访问资源。
在Kubernetes中,通过Ingress Nginx配置CORS非常简单,只需要在Ingress资源中添加特定的注解即可。以下是核心注解及其功能:
1、nginx.ingress.kubernetes.io/enable-cors : 启用CORS支持,设置为“true”
2、nginx.ingress.kubernetes.io/cors-allow-origin : 指定允许访问的源,可以是具体域名或“*”(允许所有)
3、nginx.ingress.kubernetes.io/cors-allow-methods : 指定允许的HTTP方法
4、nginx.ingress.kubernetes.io/cors-allow-headers : 指定允许的请求头
5、nginx.ingress.kubernetes.io/cors-allow-credentials : 是否允许发送凭据(如cookies)
以下是一个完整的Ingress资源配置示例,展示了如何为后端API服务配置CORS:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
namespace: production
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: " https://app.mycompany.com "
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization"
nginx.ingress.kubernetes.io/cors-expose-headers: "Content-Length,Content-Range"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-max-age: "1728000"
spec:
ingressClassName: nginx
rules:
- host: api.mycompany.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80801、多域名配置:可以通过逗号分隔多个允许的源
nginx.ingress.kubernetes.io/cors-allow-origin: " https://app1.mycompany.com , https://app2.mycompany.com "2、正则表达式匹配:使用正则表达式匹配允许的域名
nginx.ingress.kubernetes.io/cors-allow-origin-regex: ' https://.*\.mycompany\.com'3、预检请求缓存:设置预检请求的缓存时间
nginx.ingress.kubernetes.io/cors-max-age: "86400"配置完成后,可以通过以下方式验证CORS是否生效:
1、使用浏览器开发者工具查看响应头,确认包含正确的CORS头
2、使用curl命令测试:
curl -I -X OPTIONS -H "Origin: https://app.mycompany.com " https://api.mycompany.com 可以看到以下响应头:
Access-Control-Allow-Origin: https://app.mycompany.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization总结
一、先弄清 3 件事
1、谁产生 CORS 错误?
浏览器。服务器只要返回合规的 Access-Control-* 响应头即可。
2、预检请求(OPTIONS)必须返回 2xx,否则浏览器直接阻断后续真实请求。
3、Ingress-Nginx 已经帮我们封装好了所有 Nginx 指令,直接写注解就能生效。
二、最小可用配置(开放全部域名,快速验证)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api
annotations:
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend
port:
number: 80应用后浏览器即可跨域访问 https://api.example.com 下的所有接口 。
三、生产级安全加固配置(推荐)
注解 | 作用 | 示例值 |
|---|---|---|
enable-cors | 总开关 | “true” |
cors-allow-origin | 允许的源 | “https://a.com,https://b.com” (≥1.9.0 支持多域名逗号分隔) |
cors-allow-methods | 允许的 HTTP 方法 | “GET, POST, PUT, DELETE, OPTIONS” |
cors-allow-headers | 允许的请求头 | “DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization” |
cors-expose-headers | 前端可读取的响应头 | “Content-Length,Content-Range,X-Custom-Header” |
cors-allow-credentials | 是否允许携带 Cookie | “true” (此时 cors-allow-origin 不能为 * ) |
cors-max-age | 预检缓存时间(秒) | “86400” |
四、老版本不支持多域名处理方法
Ingress-Nginx < 1.9.0 只能写一条 cors-allow-origin 。
解决方案:用 configuration-snippet 动态返回请求头,兼容任意域名列表/正则。
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
# 允许的域名列表
map_hash_bucket_size 128;
map $http_origin $cors_allow {
default "";
"~^https?://(localhost|a\.com|b\.com)(:\\d+)?$" "$http_origin";
}
more_set_headers "Access-Control-Allow-Origin: $cors_allow";
more_set_headers "Access-Control-Allow-Credentials: true";
more_set_headers "Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS";
more_set_headers "Access-Control-Allow-Headers: DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization";
if ($request_method = OPTIONS ) {
more_set_headers "Access-Control-Max-Age: 86400";
more_set_headers "Content-Type: text/plain; charset=utf-8";
more_set_headers "Content-Length: 0";
return 204;
}五、一键验证是否生效
# 预检请求
curl -i -X OPTIONS \
-H "Origin: https://app.example.com" \
-H "Access-Control-Request-Method: POST" \
https://api.example.com/users
# 正确应返回
HTTP/2 204
access-control-allow-origin: https://app.example.com
access-control-allow-methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
access-control-allow-credentials: true1、避免使用 * 作为允许的源,除非是公共API;
2、对于需要身份验证的API,确保设置 cors-allow-credentials: “true”;
3、限制允许的HTTP方法,只开放必要的操作;
4、定期审查和更新CORS策略,确保与业务需求和安全要求保持一致;
5、最小可用:仅 enable-cors: “true” 和 cors-allow-origin: “*” 。;
6、生产安全(1)明确 origin 白名单;(2)按需开启 allow-credentials;(3) 配置 max-age 减少预检流量;
7、老版本或多域名场景:用 configuration-snippet 动态写头;
通过合理配置Ingress Nginx的CORS策略,可以安全高效地解决前后端分离架构中的跨域问题,提升开发效率和用户体验。
如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!
本文分享自 Nicholas与Pypi 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!