为Nginx Ingress配置跨域访问
在Web开发中,由于浏览器的同源策略,一个域下的网页通常不能直接请求另一个域下的资源。CORS(跨资源共享,Cross-Origin Resource Sharing)提供了一种安全的方式来绕过这个限制,允许跨域请求。
使用CORS允许跨域访问的场景较多,可能的场景如下:
- 前后端分离:前端应用部署在一个域名下(如 frontend.example.com),而后端API服务使用另一个域名(如 api.example.com),前端应用在尝试从API服务获取数据时会遇到跨域资源共享问题,需要配置CORS允许跨域访问。
- 第三方服务集成:网站可能需要调用第三方服务(例如地图服务、社交平台登录等)的API接口,则需要配置CORS允许跨域访问。
- 使用内容分发网络CDN:静态资源可能通过CDN提供,而CDN域名与主站域名不同,需要使用跨域访问来加载这些资源。
为Nginx Ingress配置跨域访问示例
本文以一个前端应用程序(frontend.example.com)与后端API服务(api.example.com)通信为例,在Ingress资源的Annotations部分添加指定注解配置跨域访问,注解详情请参见Enable CORS。
为Nginx Ingress配置跨域访问示例如下:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress namespace: default annotations: nginx.ingress.kubernetes.io/enable-cors: "true" # 启用CORS跨域访问 nginx.ingress.kubernetes.io/cors-allow-origin: "*" # 允许访问的域 nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS" # 允许的HTTP请求方法 nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range" # 允许的请求头 nginx.ingress.kubernetes.io/cors-expose-headers: "Content-Length,Content-Range" # 需要公开的响应头 nginx.ingress.kubernetes.io/cors-max-age: "3600" # 预检请求的缓存时长 spec: rules: - host: api.example.com http: paths: - path: / backend: service: name: example port: number: 80 property: ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH pathType: ImplementationSpecific ingressClassName: nginx
参数 |
说明 |
配置示例 |
---|---|---|
nginx.ingress.kubernetes.io/enable-cors |
启用CORS设置,允许跨域访问。 |
nginx.ingress.kubernetes.io/enable-cors: "true" |
nginx.ingress.kubernetes.io/cors-allow-origin |
指定Access-Control-Allow-Origin响应头的值,表示允许访问的域。 格式为“http(s)://example.com”或“http(s)://example.com:port”,可填写多个值,以英文逗号分隔。 同时支持使用通配符,例如:
须知:
出于安全考虑,建议指定确切的域名,防止未经授权的域访问敏感资源。 |
nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com" |
nginx.ingress.kubernetes.io/cors-allow-methods |
指定Access-Control-Allow-Methods响应头的值,表示允许的HTTP请求方法。 可填写多个值,以英文逗号分隔。 |
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS" |
nginx.ingress.kubernetes.io/cors-allow-headers |
指定Access-Control-Allow-Headers响应头的值,表示允许的请求头。 可填写多个值,以英文逗号分隔。 |
nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range" |
nginx.ingress.kubernetes.io/cors-allow-credentials |
指定Access-Control-Allow-Credentials响应头的值,表示是否允许发送凭据(如Cookies)。 取值如下:
须知:
由于安全策略限制,当Access-Control-Allow-Credentials设置为true时,Access-Control-Allow-Origin不能设置为允许所有域名访问,即不能设为通配符"*",防止未经授权的域访问敏感资源,例如携带用户凭证信息的Cookies或者Authorization头部等。 |
nginx.ingress.kubernetes.io/cors-allow-credentials: "true" |
nginx.ingress.kubernetes.io/cors-expose-headers |
指定Access-Control-Expose-Headers响应头的值,表示可以被跨域请求读取的自定义响应头部,例如通过客户端的JavaScript代码获取非标准响应头字段。 默认情况下出于安全考虑,浏览器在处理跨域请求时只能访问标准的响应头,包括Cache-Control、Content-Language、Content-Type、Expires、Last-Modified和Pragma。 可填写多个值,以英文逗号分隔。 |
nginx.ingress.kubernetes.io/cors-expose-headers: "Content-Length,Content-Range" |
nginx.ingress.kubernetes.io/cors-max-age |
指定Access-Control-Max-Age响应头的值,表示CORS预检请求的缓存时长。 该参数值应该根据实际需求合理设置。如果设置得太短,可能会导致频繁的预检请求;如果设置得太长,可能会在CORS策略更新后延迟生效。 |
nginx.ingress.kubernetes.io/cors-max-age: "3600" |
验证跨域访问配置是否生效
使用curl命令行工具发送跨域请求,并检查响应头部。
curl -X OPTIONS -H 'Origin: {源站点}' {Ingress访问URL} -i
例如,本示例中源站点为frontend.example.com,访问的Ingress URL为api.example.com,则命令如下:
curl -X OPTIONS -H 'Origin: frontend.example.com' api.example.com -i
回显如下,跨域访问会在原始后端响应中添加Access-Control-**相关的请求头:
HTTP/1.1 200 OK Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS Access-Control-Allow-Headers: DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range Access-Control-Expose-Headers: Content-Length,Content-Range Access-Control-Allow-Credentials: true Content-Type: application/json