Ingress下跨域资源共享(CORS)配置详解

- Kubernetes

本文将详细介绍 ingress 下 cors 相关内容。包括 CORS 是什么?Ingress 中什么情况下需要启用 CORS?Ingress 如何启用 CORS?Ingress 中 CORS 相关注释作用以及 CORS 相关 HTTP headers等。
2024-04-13T08:31:33.png


CORS 是什么?

CORS 是跨域资源共享(Cross-Origin Resource Sharing)的缩写,用于在浏览器中允许一个网页的代码去请求不同域名下的资源。其由一组 headers 组成,这些 headers 的响应指示是否允许跨域。

在传统的同源策略(Same-Origin Policy)下,浏览器要求请求必须和页面的源(协议、域名和端口)保持一致。否则,浏览器会阻止跨域请求。这个限制是基于安全考虑,以防止恶意网站访问用户的敏感信息。

然而,在某些场景中,需要在网页上加载来自其他域下的资源或者与其他域进行数据交互,例如使用API请求数据。这就产生了跨域请求,而CORS就解决了跨域资源共享的问题。

Ingress 什么情况下需要启用 CORS?

通过上面的描述,我们了解到CORS主要用于浏览器的安全控制,以决定是否允许用户在浏览前端页面时发起跨域请求。基于这一了解,我们可以根据需求来决定是否为ingress启用CORS配置:




Ingress 如何启用 CORS?

ingress 启用 CORS 需要分两步,首先要调整 ingress-nginx-controller 的配置(configmap)将 allow-snippet-annotations 值设置为 true 以允许用户在 Ingress 对象中添加自定义的 -snippet 注释或指令。

[root@imzcy ~]# kubectl get cm ingress-nginx-controller -n ingress-nginx -o yaml
apiVersion: v1
data:
  allow-snippet-annotations: "true"
kind: ConfigMap
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
[root@imzcy ~]#

然后是在具体的 ingress 对象中启用 CORS 相关配置


apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "*"
  name: ing-imzcy-cors
  namespace: test
spec:
  ingressClassName: nginx-wan
  rules:
  - host: cors.zcytest.cn
    http:
      paths:
      - backend:
          service:
            name: service-nginx-new
            port:
              number: 80
        path: /
        pathType: Prefix

模拟预检请求验证CORS配置结果(只需要指定方法为 OPTIONS 并且请求中加上名为 Origin 的头即可)

[root@worker-01 ~/cors]# curl -svXOPTIONS -H 'Host: cors.zcytest.cn' -H 'Origin: imzcy.example.com' http://192.168.3.15
* About to connect() to 192.168.3.15 port 80 (#0)
*   Trying 192.168.3.15...
* Connected to 192.168.3.15 (192.168.3.15) port 80 (#0)
> OPTIONS / HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> Host: cors.zcytest.cn
> Origin: imzcy.example.com
> 
< HTTP/1.1 204 No Content
< Date: Sun, 25 Feb 2024 16:17:30 GMT
< Connection: keep-alive
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS
< Access-Control-Allow-Headers: DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization
< Access-Control-Max-Age: 1728000
< Content-Length: 0
< 
* Connection #0 to host 192.168.3.15 left intact
[root@worker-01 ~/cors]#




Ingress 中 CORS 相关注释

1、nginx.ingress.kubernetes.io/enable-cors
作用:指定是否启用 CORS

2、nginx.ingress.kubernetes.io/cors-allow-origin
作用:指定 CORS 允许的域。
默认值: "*" ,表示允许所有。
此注释可以英文逗号分隔指定多个域,格式为:http(s)://example.com 或 http(s)://example.com:port 。

示例:

"*"
"https://example.com:1443, http://example.com"
"https://*.example:1443, http://*.example.com, http://example.org"


3、nginx.ingress.kubernetes.io/cors-allow-methods
作用:指定 CORS 允许的方法。

默认值:GET, PUT, POST, DELETE, PATCH, OPTIONS。

此注释可以英文逗号分隔指定多个值,但仅接受大写或小写字母。

示例:

"PUT, GET, POST, OPTIONS"


4、nginx.ingress.kubernetes.io/cors-allow-headers
作用:指定 CORS 允许的头。

默认值:DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization。

此注释可以英文逗号分隔指定多个值,但仅接受字母、数字、下划线以及短横线。

示例:

"X-Forwarded-For, X-clb-xxxx"


5、nginx.ingress.kubernetes.io/cors-expose-headers
作用:指定 CORS 哪些头可以向响应中公开。

默认值:无。

此注释可以英文逗号分隔指定多个值,但仅接受字母、数字、下划线、中横线和*。

示例:

"Content-Disposition, Content-Type, Cache-Control"


6、nginx.ingress.kubernetes.io/cors-allow-credentials
作用:指定是否可以在 CORS 操作期间传递凭据。

默认值:true 。

示例:

"false"


7、nginx.ingress.kubernetes.io/cors-max-age
作用:指定预检请求的缓存时间,单位为秒。

默认值:1728000 。即 48 小时。

示例:

600




CORS HTTP headers

HTTP 请求

Origin:指定发起跨域请求的源。

Access-Control-Request-Method:指定将来对同一资源的CORS请求可能使用的方法。

Access-Control-Request-Headers:指定将来对同一资源的CORS请求可能使用的标头。


HTTP 响应

Access-Control-Allow-Origin:允许访问跨域资源的来源。

Access-Control-Allow-Methods:指定服务器允许的跨域请求方法。

Access-Control-Allow-Headers:指定服务器允许的跨域请求中可以包含的自定义头部字段。

Access-Control-Expose-Headers:指定客户端可以访问的响应头部字段。

Access-Control-Allow-Credentials:是否允许在跨域请求中发送和接收身份凭证信息。

Access-Control-Max-Age:指定预检请求结果被缓存的时间。




相关参考:

https://fetch.spec.whatwg.org/#cors-protocol

https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#enable-cors

以上内容仅代表个人观点,不足之处还请指正交流。