在前端开发中,会通过 fetch 发起网络请求获取数据,然后再显示到页面上,这也就是我们常说的前后端分离。

但是受限于浏览器的同源策略, fetch 是不能跨域访问的,这时候就需要我们设置服务端响应的头信息,来达到跨域的目的,而Caddy的反向代理,天生就具备这个能力。

什么是同源策略

同源策略是浏览器的一项非常重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

我们看下它的定义:

同源策略是指在Web浏览器中,允许某个网页脚本访问另一个网页的数据,但前提是这两个网页必须有相同的URI、主机名和端口号,一旦两个网站满足上述条件,这两个网站就被认定为具有相同来源

同源策略对Web应用程序具有特殊意义,因为Web应用程序广泛依赖于HTTP cookie来维持用户会话,所以必须将不相关网站严格分隔,以防止丢失数据泄露。

头信息设置

在Caddy的反向代理中,为我们提供了两个指令来设置请求头和响应头的信息,他们分别是header_up和header_down,他们的指令设置规则如下所示:

1
2
3
4
5
6
7
8
reverse_proxy [<matcher>] [<upstreams...>] {
    # backends
    to <upstreams...>
	...
    # header manipulation
    header_up   [+|-]<field> [<value|regexp> [<replacement>]]
    header_down [+|-]<field> [<value|regexp> [<replacement>]]
}
  1. header_up :用于添加、移除和设置客户端到上游主机(后端)的请求头信息。也就是说利用它,可以修改客户端请求的头信息,然后再传给上游后端服务。看到它后面的 +|- 表达式了吗? + 表示添加一个头信息, - 表示移除一个头信息,都没有的时候表示设置一个头信息。可以同时有多个header_up
  2. header_down : 和header_up 的作用一样,只不过它是用于修改后端服务响应的头信息,然后再传给客户端,方向正好是反的。

只介绍使用,可能会觉得有点绕,下面我们通过一个示例来看下就明白了,和我们平时设置头信息差不多的。

1
2
3
4
5
6
7
8
9
https://example.com {
   reverse_proxy /path http://localhost:54321 {
      header_up Host {host}
      header_up X-Real-IP {remote}
      header_up X-Forwarded-For {remote}
      header_up X-Forwarded-Port {server_port}
      header_up X-Forwarded-Proto "http"
   }
}

以上就是一个重新设置Host、X-Real-IP等请求头的示例,通过 header_up 设置,一行设置一个,非常简单。 这里需要留意的是 {host} 这些占位符,他们是Caddy预定义的,可以理解为一个变量,可以在Caddyfile中使用,Nginx也有类似的占位符,只不过是以 $ 开头的。

实现跨域访问

无法跨域的时候,浏览器会返回403的错误:No ‘Access-Control-Allow-Origin’ header is present on the requested resource,从这个我们就能看到需要设置 Access-Control-Allow-Origin 这个头信息,而且是返回的响应头信息,下面我们看下如何在Caddy中配置跨域访问。

1
2
3
4
5
6
7
https://example.com {
   reverse_proxy /path http://localhost:54321 {
      header_up Host {http.reverse_proxy.upstream.hostport} 
      header_down Access-Control-Allow-Headers * 
      header_down Access-Control-Allow-Origin *
   }
}

以上实现跨域的重点在于header_down 的设置,这里的header_up 也一种比较好的安全措施,后端可以根据Host校验请求是否合法。 以上设置后,就可以跨域访问了,非常简单。

小结

跨域只是头信息设置的一种使用场景,其他还有很多,结合头信息,可以自由发挥使用,从这个也可以发现,相比Nginx,Caddy还是比较轻的。

本文为原创文章,转载注明出处,欢迎扫码关注公众号flysnow_org或者网站asf http://www.flysnow.org/ ,第一时间看后续精彩文章。觉得好的话,请猛击文章右下角「好看」,感谢支持。

扫码关注