如何使用 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 仅适用于浏览器和 html。 curl
不在乎。因此,如果您将服务限制为只能从您的域访问,那么其他站点将无法访问它。
为了让您的服务可供他们使用 - 这些网站可以设置 nginx 或 apache 来将一些流量转发到您的服务。因此,3d 方站点将使用配置了自己的 CORS 访问他们自己的主机,并且他们的主机将与您的服务进行通信。
另一种(类似的)解决方案是为您设置 2 个指向相同服务的主机名(子域?)。并将一个暴露给您自己的站点(使用严格的 CORS),另一个暴露给外部客户。
【讨论】:
以上是关于如何使用 CORS 保护 REST API?的主要内容,如果未能解决你的问题,请参考以下文章
Yammer REST API - 如何从不同来源 (CORS) 获取数据?
当我的目标是动态时如何解决 Rest API 的 CORS 错误
如何在我的 Django REST api 上调试启用 CORS