第13章 杂项

上一章

13.2 URL重定向

下一章

更多图书

13.1 CORS

跨域资源共享(CORS)是一种机制,它使用额外的HTTP头来告诉浏览器让运行在一个域名上的Web应用可以访问来自不同源服务器上的指定资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求另外一个资源时,资源会发起一个跨域HTTP请求。

比如,站点http://domain-a.com 的某HTML页面通过<img>的src请求http://domain-b.com/image.jpg 。出于安全原因,浏览器限制跨域HTTP请求。可以通过配置CORS头来解除这种限制。更深入的内容可以参考如下两篇文章:

·http://www.ruanyifeng.com/blog/2016/04/cors.html

·https://developer.mozilla.org/zh-CN/docs/Web/HTTP/AccesscontrolCORS

Istio提供了CORS的配置,我们可以在VirtualService中配置CORS。

服务service-go配置CORS示例如下:


1 apiVersion: networking.istio.io/v1alpha3
 2 kind: VirtualService
 3 metadata:
 4   name: service-go-cors
 5 spec:
 6   hosts:
 7   - service-go
 8   http:
 9   - route:
 10     - destination:
 11         host: service-go
 12     corsPolicy:
 13       allowOrigin:
 14       - http://www.will.com
 15       allowMethods:
 16       - POST
 17       - GET
 18       allowHeaders:
 19       - X-Custom-Header
 20       exposeHeaders:
 21       - X-Expose-Header
 22       maxAge: 24h
 23       allowCredentials: false

第12~23行定义了服务service-go的CORS设置,allowOrigin表示允许跨域的域名,allowMethods表示允许跨域的HTTP方法,allowHeaders表示在请求时允许携带的请求头,exposeHeaders表示允许暴露的请求响应头,maxAge表示跨域预检查的缓存时间,allowCredentials表示是否允许发送Cookie。

【实验】

1)创建测试Pod:


$ kubectl apply -f kubernetes/dns-test.yaml

2)创建service-go服务的CORS规则:


$ kubectl apply -f istio/miscellaneous/virtual-service-go-cors.yaml

3)简单请求访问测试:


$ kubectl exec dns-test -c dns-test -- curl -sv -H "Origin: http://www.will.com" http://service-go/env
> GET /env HTTP/1.1
> User-Agent: curl/7.35.0
> Host: service-go
> Accept: */*
> Origin: http://www.will.com
> 
{"message":"go v2"}< HTTP/1.1 200 OK
< content-type: application/json; charset=utf-8
< date: Sat, 19 Jan 2019 05:54:22 GMT
< content-length: 19
< x-envoy-upstream-service-time: 18
< server: envoy
< access-control-allow-origin: http://www.will.com
< access-control-expose-headers: X-Expose-Header
< 
{ [data not shown]
$ kubectl exec dns-test -c dns-test -- curl -sv -H "Origin: http://not-allowed-origin.will.com" http://service-go/env
> GET /env HTTP/1.1
> User-Agent: curl/7.35.0
> Host: service-go
> Accept: */*
> Origin: http://not-allowed-origin.will.com
> 
{"message":"go v2"}< HTTP/1.1 200 OK
< content-type: application/json; charset=utf-8
< date: Sat, 19 Jan 2019 05:55:22 GMT
< content-length: 19
< x-envoy-upstream-service-time: 1
< server: envoy
< 
{ [data not shown]

4)非简单请求访问测试。

预检请求:


$ kubectl exec dns-test -c dns-test -- curl -sv -X OPTIONS -H "Origin: http://www.will.com" -H "Access-Control-Request-Method: GET" -H "Access-Control-Request-Headers: X-Custom-Header" http://service-go/env
> OPTIONS /env HTTP/1.1
> User-Agent: curl/7.35.0
> Host: service-go
> Accept: */*
> Origin: http://www.will.com
> Access-Control-Request-Method: GET
> Access-Control-Request-Headers: X-Custom-Header
> 
< HTTP/1.1 200 OK
< access-control-allow-origin: http://www.will.com
< access-control-allow-methods: POST,GET
< access-control-allow-headers: X-Custom-Header
< access-control-max-age: 24h0m0s
< access-control-expose-headers: X-Expose-Header
< date: Sat, 19 Jan 2019 05:56:18 GMT
< server: envoy
< content-length: 0
< 
$ kubectl exec dns-test -c dns-test -- curl -sv -X OPTIONS -H "Origin: http://not-allowed-origin.will.com" -H "Access-Control-Request-Method: GET" -H "Access-Control-Request-Headers: X-Custom-Header" http://service-go/env
> OPTIONS /env HTTP/1.1
> User-Agent: curl/7.35.0
> Host: service-go
> Accept: */*
> Origin: http://not-allowed-origin.will.com
> Access-Control-Request-Method: GET
> Access-Control-Request-Headers: X-Custom-Header
> 
< HTTP/1.1 404 Not Found
< date: Sat, 19 Jan 2019 05:57:32 GMT
< server: envoy
< content-length: 0
< x-envoy-upstream-service-time: 1
<

正常请求:


$ kubectl exec dns-test -c dns-test -- curl -sv -H "Origin: http://www.will.com" -H "X-Custom-Header: value" http://service-go/env
> GET /env HTTP/1.1
> User-Agent: curl/7.35.0
> Host: service-go
> Accept: */*
> Origin: http://www.will.com
> X-Custom-Header: value
> 
{"message":"go v2"}< HTTP/1.1 200 OK
< content-type: application/json; charset=utf-8
< date: Sat, 19 Jan 2019 05:57:58 GMT
< content-length: 19
< x-envoy-upstream-service-time: 1
< server: envoy
< access-control-allow-origin: http://www.will.com
< access-control-expose-headers: X-Expose-Header
< 
{ [data not shown]
$ kubectl exec dns-test -c dns-test -- curl -sv -H "Origin: http://not-allowed-origin.will.com" -H "X-Custom-Header: value" http://service-go/env
> GET /env HTTP/1.1
> User-Agent: curl/7.35.0
> Host: service-go
> Accept: */*
> Origin: http://not-allowed-origin.will.com
> X-Custom-Header: value
> 
{"message":"go v2"}< HTTP/1.1 200 OK
< content-type: application/json; charset=utf-8
< date: Sat, 19 Jan 2019 05:58:40 GMT
< content-length: 19
< x-envoy-upstream-service-time: 17
< server: envoy
< 
{ [data not shown]

从上面的请求测试可以得出如下的结论:当使用允许的域名进行跨域请求时,返回的响应头中都会有浏览器跨域请求需要的Access-Control-Allow-Origin等字段。当使用了其他不被允许的域名进行跨域资源请求时,请求的响应中并不包含浏览器跨域请求资源时需要的响应头。

5)清理:


$ kubectl delete -f kubernetes/dns-test.yaml
$ kubectl delete -f istio/miscellaneous/virtual-service-go-cors.yaml