利用 APISIX 优雅解决 Web 应用中的跨域问题

更新时间 1/27/2024

在 Web 应用开发中,跨域问题已经成为一个老生常谈的话题。但随着 API 网关的普遍应用,我们拥有了更加便捷高效的解决方案来应对跨域问题。API 网关作为应用架构中的关键组件,不仅提供了请求路由、API 管理等功能,还能有效地处理跨域请求,帮助开发者绕过浏览器的同源策略限制。本文将详细介绍如何使用 APISIX 这一 API 网关来解决跨域问题。

什么是跨域

跨域问题主要是由于浏览器的同源策略引起的。同源策略要求请求的源(协议、域名、端口)必须与目标资源完全一致,否则浏览器会阻止该请求。这种策略主要是为了保护用户的信息安全,防止恶意网站窃取数据。但在实际开发中,前后端分离、使用不同的域名或端口进行部署等情况经常导致跨域问题。

使用 APISIX 解决跨域问题

CORS(跨域资源共享)

CORS 是一个 W3C 标准,它允许浏览器向跨域服务器发送请求,从而克服了同源策略的限制。在 APISIX 中,开发者可以通过 CORS 插件轻松的配置 CORS 规则,指定允许哪些来源的请求访问资源。

1curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "uri": "/hello", "plugins": { "cors": {} }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:8080": 1 } } }'

这行命令使用 curl 向 APISIX 的 Admin API 发送一个 PUT 请求,创建了 ID 为 1 的路由,其中设置了 URI 路径为 /hello,以默认配置启用了 CORS 插件,并指定了上游服务器为 127.0.0.1:8080。 发送测试请求可以得到默认的配置结果:

1curl http://127.0.0.1:9080/hello -v
2
3...
4< Server: APISIX web server
5< Access-Control-Allow-Origin: *
6< Access-Control-Allow-Methods: *
7< Access-Control-Allow-Headers: *
8< Access-Control-Expose-Headers: *
9< Access-Control-Max-Age: 5
10...

如果需要调整 CORS 策略,只需简单地修改相关插件的配置即可。以下是几个常用的配置项:

  • allow_origins:允许跨域访问的 Origin,可以是一个具体的 URL,也可以使用通配符 * 表示允许所有 Origin。多个值之间使用逗号分隔。
  • allow_methods:允许跨域访问的 HTTP 方法,如 GET、POST 等。多个值之间使用逗号分隔。
  • allow_headers:允许跨域请求时携带的自定义头部字段。多个值之间使用逗号分隔。
  • expose_headers:允许跨域响应时暴露的自定义头部字段。多个值之间使用逗号分隔。
  • max_age:浏览器缓存 CORS 响应的最大时间
  • allow_credentials:是否允许携带凭证(如 Cookies)进行跨域请求。

CORS

注意点

要特别注意的是,CORS 虽然方便,但开启后可能会遇到一些安全问题,主要是因为 CORS 放宽了同源策略的限制,允许来自不同源的请求访问资源。

这里重点说说 allow_credentialsallow_credentials 是 CORS 中一个非常重要的配置项,它用于确定是否允许跨域请求携带认证信息,这包括但不限于 Cookies、HTTP 认证信息或客户端 SSL 证书等敏感数据。

默认情况下,allow_credentials 是禁用的,即不允许携带认证信息。但如果开启了 CORS 并允许携带认证信息(allow_credentials: true),那么必须格外小心。因为这意味着来自其他源的请求也可以访问受保护的资源,甚至可能执行敏感操作。例如,如果恶意网站利用这一配置漏洞,可能会诱导用户发起跨域请求,从而窃取他们的会话 Cookies 或执行其他未授权的操作。

为了最大限度地减少开启跨域后可能遇到的安全问题。应该遵循以下几点最佳实践:

  1. 谨慎配置 allow_origin:不要随意将 allow_origin 设置为 *(允许所有来源),而应该明确指定允许访问的源。
  2. 限制 allow_credentials:只有在必要时才启用 allow_credentials,并且仅对可信任的源开放。
  3. 使用安全的传输协议:确保 CORS 请求通过 HTTPS 进行传输,以防止中间人攻击。
  4. 验证和授权:在后端服务器上,对跨域请求进行适当的验证和授权检查,确保只有授权用户能够访问敏感资源。
  5. 避免使用不安全的 HTTP 方法:限制跨域请求使用的 HTTP 方法,例如只允许 GET 和 POST,而禁用 PUT、DELETE 等可能引发安全风险的方法。

反向代理

除了使用 CORS 之外,APISIX 还可以通过配置为反向代理来间接解决跨域问题。反向代理是一种常用的服务器架构模式,在这种模式中,反向代理服务器充当了客户端与目标服务器之间的中间人。当客户端发起请求时,这些请求首先被发送到反向代理服务器,再由它转发给实际的目标服务器。完成处理后,目标服务器的响应会返回给反向代理,最终由反向代理传递回客户端。

Reverse Proxy

重要的是要理解,反向代理本身并不直接解决跨域问题,而是通过一种巧妙的方式绕过了浏览器的同源策略限制。当客户端需要进行跨域请求时,它实际上是向反向代理服务器,而不是直接向目标服务器发送请求。由于反向代理服务器和目标服务器通常位于同一网络环境或配置下,它们之间的通信不受同源策略的限制。这样,反向代理服务器可以自由地将客户端的请求转发给目标服务器,并将得到的响应返回给客户端,从而间接实现了跨域访问的目的。

而 APISIX 作为一个 API 网关,天然就应部署客户端与服务端之间。因此,在一些规模较小的应用中,可以将与客户端应用与 APISIX 部署在同一个域,并将客户端请求的地址改为 APISIX 服务地址,确保客户端能顺利访问到 APISIX,从而利用反向代理的功能为客户端提供跨域访问的能力,同时还能搭配其他插件来确保整个通信过程的安全性和可靠性。

总结

在本文中,我们探讨了如何使用 APISIX 解决跨域问题,重点介绍了两种实现跨域的方法:CORS 和反向代理。通过合理配置 CORS 插件,我们可以放宽浏览器的同源策略限制,允许跨域请求访问资源。而反向代理则通过充当“中间人”的角色,绕过浏览器的同源策略,实现了跨域访问。这两种方法各有优势,可以根据具体需求选择适合的解决方案。无论是使用 CORS 还是反向代理,APISIX 都能提供了灵活且强大的功能,帮助开发者轻松解决跨域问题,确保应用的正常运行和用户体验。

微信咨询

获取方案