如何使用 CORS 保护 REST API?

Posted

技术标签:

【中文标题】如何使用 CORS 保护 REST API?【英文标题】:How to protect REST API with CORS? 【发布时间】:2018-06-04 13:09:06 【问题描述】:

我正在开发一个 Web 应用程序,前端和各种客户端 (curl & co.) 都可以通过 REST API 访问数据。前端和后端都将在同一个域上。我想用 CORS 保护我的前端,这对我来说是一个两难的选择。如果我将Access-Control-Allow-Origin 设置为*,那么所有其他客户端都可以访问API,但我自己的前端会更加暴露。另一方面,将其设置为我的域会强制客户端提供(假)Origin 标头,并有效地禁止将浏览器用作客户端(通过不同域上的前端)。

这通常是如何解决的?我应该为 API 使用两个不同的端点,一个用于公共访问,另一个用于我的前端?我会很感激一些建议。

【问题讨论】:

当您调用同一个函数时,您的客户端(您的前端和其他客户端)是否可以访问不同的功能,或者您是否返回不同的数据(例如:更多数据到您的网站)? 不,功能是一样的。当然,每个用户都经过身份验证,因此每个用户的数据不同(但每个用户可以使用我的前端或他们自己的客户端,他们会得到相同的数据)。 【参考方案1】:

我想用 CORS 保护我的前端

CORS 不保护前端的任何内容,CORS 是一种防止来自未经授权的网站的跨站点脚本的方法。 CORS 标头仅对浏览器的 XHR 调用有效。它不会阻止直接加载资源。

如果我将 Access-Control-Allow-Origin 设置为 *,那么所有其他客户端都可以访问 API,但我自己的前端会更加暴露。

恕我直言,您的前端将像以前一样访问。 CORS 标头仅对浏览器的 XHR 调用有效

另一方面,将其设置为我的域会强制客户端提供(假)Origin 标头,并有效地禁止使用浏览器作为客户端(通过不同域上的前端)。

不是真的。 有几种选择:

1234563 /p>

浏览器(在 XHR 调用中)发送 Origin 标头,您可以检查并发送或拒绝来自 Origin 标头的主机名

并且非浏览器客户端不受 CORS 标头的限制。

我是否应该为 API 使用两个不同的端点,一个用于公共访问,另一个用于我的前端?我会很感激一些建议

如 cmets 中所写 - 假设功能相同且用户已通过身份验证,那么恕我直言,为内部/公共使用单独的服务是没有意义的。

这些都是针对特定问题的答案,但我仍然不相信你想达到什么/为什么/如何达到目的。

【讨论】:

【参考方案2】:

CORS 仅适用于浏览器和 htmlcurl 不在乎。因此,如果您将服务限制为只能从您的域访问,那么其他站点将无法访问它。

为了让您的服务可供他们使用 - 这些网站可以设置 nginx 或 apache 来将一些流量转发到您的服务。因此,3d 方站点将使用配置了自己的 CORS 访问他们自己的主机,并且他们的主机将与您的服务进行通信。

另一种(类似的)解决方案是为您设置 2 个指向相同服务的主机名(子域?)。并将一个暴露给您自己的站点(使用严格的 CORS),另一个暴露给外部客户。

【讨论】:

以上是关于如何使用 CORS 保护 REST API?的主要内容,如果未能解决你的问题,请参考以下文章

如何保护同一服务器上前端使用的 Rest API 端点?

Yammer REST API - 如何从不同来源 (CORS) 获取数据?

当我的目标是动态时如何解决 Rest API 的 CORS 错误

如何在我的 Django REST api 上调试启用 CORS

如何使用 REST + CodeceptJS 测试 API,访问受 Auth0 保护?

如何使用邮递员测试 Django REST 框架登录保护 API?