本文将详细介绍 ingress 下 cors 相关内容。包括 CORS 是什么?Ingress 中什么情况下需要启用 CORS?Ingress 如何启用 CORS?Ingress 中 CORS 相关注释作用以及 CORS 相关 HTTP headers等。
CORS 是什么?
CORS 是跨域资源共享(Cross-Origin Resource Sharing)的缩写,用于在浏览器中允许一个网页的代码去请求不同域名下的资源。其由一组 headers 组成,这些 headers 的响应指示是否允许跨域。
在传统的同源策略(Same-Origin Policy)下,浏览器要求请求必须和页面的源(协议、域名和端口)保持一致。否则,浏览器会阻止跨域请求。这个限制是基于安全考虑,以防止恶意网站访问用户的敏感信息。
然而,在某些场景中,需要在网页上加载来自其他域下的资源或者与其他域进行数据交互,例如使用API请求数据。这就产生了跨域请求,而CORS就解决了跨域资源共享的问题。
- 浏览器在发起请求时会检查目标资源的域名、协议和端口号,如果和当前页面的不同,则认为是跨域请求。
- 对于跨域请求,浏览器会先发送一个 OPTIONS 预检请求(请求类型为复杂请求时才会发送预检请求),用于向服务器获取跨域请求的许可(即是否允许实际的跨域请求)。预检请求的头部中会包含Origin字段,它指示了请求的来源域。
- 服务器接收到预检请求后,会发送带有特定CORS头部的响应。这些头部可能包括Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers等字段,用于指示是否允许实际的跨域请求,以及允许使用的方法和头部字段。
- 如果服务器响应状态码为200或204,响应头中带有Access-Control-Allow-Origin字段并且其值与请求的来源域匹配(或为通配符*,表示允许任意来源)则判断允许跨域,浏览器就会将实际的跨域请求发送到服务器。否则,浏览器会阻止实际的跨域请求,且不允许网页访问响应的数据。
Ingress 什么情况下需要启用 CORS?
通过上面的描述,我们了解到CORS主要用于浏览器的安全控制,以决定是否允许用户在浏览前端页面时发起跨域请求。基于这一了解,我们可以根据需求来决定是否为ingress启用CORS配置:
- 在前后端分离的场景中,ingress 绑定的后端服务是为了给前端页面提供api获取数据,则必须要启用 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
以上内容仅代表个人观点,不足之处还请指正交流。
本文采用 知识共享署名4.0 国际许可协议进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。
如果您的问题未解决,欢迎微信扫描右侧二维码与我联系。