elasticsearch restapi cross domain - downgoon/hello-world GitHub Wiki

elasticsearch restapi 跨域访问

跨域访问

跨域配置

增加以下配置,并重启:

$ vi elasticsearch.yml

http.cors.enabled: true
http.cors.allow-credentials: true
http.cors.allow-origin: /https?:\/\/apistore.test.example.net(:[0-9]+)?/
HTTP配置项 含义
http.cors.enabled 是否支持跨域,默认为false
http.cors.allow-credentials 是否返回设置的跨域Access-Control-Allow-Credentials头,如果设置为true,那么会返回给客户端。
http.cors.allow-origin 当设置允许跨域,默认为*,表示支持所有域名,如果我们只是允许某些网站能访问,那么可以使用正则表达式。比如只允许本地地址。 /https?://localhost(:[0-9]+)?/

其他关于跨域的配置项:

HTTP配置项 含义
http.cors.allow-methods 允许跨域的请求方式,默认OPTIONS,HEAD,GET,POST,PUT,DELETE
http.cors.allow-headers 跨域允许设置的头信息,默认为X-Requested-With,Content-Type,Content-Length
http.cors.max-age 浏览器发送一个“预检”OPTIONS请求,以确定CORS设置。最大年龄定义多久的结果应该缓存。默认为1728000(20天)

问题:

  1. 一定需要重启吗?
  2. http.cors.allow-origin 必须明确指定具体的访问源的域名,如果多个源呢 ? 简单,支持Perl语法集的正则表达式。比如:http.cors.allow-origin: /https?:\/\/.*?\.example\.net(:[0-9]+)?/, 则表示 example.com 下的所有子域的,所有端口,无论http还是https协议,都可以被允许跨域访问。

跨域测试

当我们配置了跨域后,我们如何校验跨域配置呢? 最严格的方式当然是请前端工程师发起请求(不同浏览器或多或少有些区别)。便捷测试,可以用 curl命令发起。那么浏览器跨域时,发送的HTTP请求与普通请求有什么区别呢?

浏览器跨域请求与普通请求的唯一区别是:跨域请求在HTTP头中多了一个Origin: XXXX 字段。

  • 普通请求
curl 'http://10.213.44.189:10092/passport/user/_search?q=nick:zhangcong123' -i 
  • 跨域请求:被禁止的情况
$ curl 'http://10.213.44.189:10092/passport/user/_search?q=nick:zhangcong123' -i  -H 'Origin: http://test.example.com:3000'

跨域失败返回:
HTTP/1.1 403 Forbidden
  • 跨域请求:被允许的情况
$ curl 'http://10.213.44.188:10092/passport/user/_search?q=nick:zhangcong123' -i  -H 'Origin: http://passport.example.net:3000'
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://passport.example.net:3000
Access-Control-Allow-Credentials: true
Content-Type: application/json; charset=UTF-8
Content-Length: 122

{"took":2,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}

这个请求通过头字段 -H 'Origin: http://passport.example.net:3000' 模拟一个来自浏览器的跨域请求,并申明自己来自http://passport.example.net:3000,服务端通过响应头:

Access-Control-Allow-Origin: http://passport.example.net:3000
Access-Control-Allow-Credentials: true

告知浏览器允许访问。

注意: 配置的时候,被允许的域和端口是统配的,但是响应头是严格定义的(请求中的Origin是什么样的,响应中的Access-Control-Allow-Origin就是什么样的)。

参考资料