【问题标题】:Securely decouple backend and frontend (node.js server)安全地解耦后端和前端(node.js 服务器)
【发布时间】:2023-04-13 15:26:01
【问题描述】:

我最近一直在研究 node.js、REST API 和 WebSocket,以进一步了解后端和前端 Web 开发。尝试采用最佳实践时,我看到 REST API 一直在出现。现在我的问题我似乎不明白如何正确解决。

举例来说,我想让客户端/服务器解耦,为此我在后端实现了一个 REST API,这样我的前端就可以访问并获取要呈现的数据。具体(虚构)示例:假设我想建立一个租赁服务网站。现在我想为我的前端有一个端点来访问有关某些产品的信息,假设到目前为止已租用的自行车数量。我希望能够在我的前端显示这一点(通过 REST API 的帮助),但我不希望其他调用此 REST API 的人能够获取数据(因为间谍活动是一项严肃的业务而且我想让邪恶的人远离,是的,他们可以进行网络爬网,但是 bla bla)。所以本质上我希望localhost 机器能够访问(部分)REST API,但不能访问其他任何人。事情变得复杂了,因为我还希望人们能够在我的网站上创建用户,所以我希望有其他端点可以不受限制地访问,因为我在想,如果在某个时候我会怎样?希望有一个与服务集成的移动应用程序。那么将所有请求限制为localhost是不可行的。

您将如何构建像这样的安全服务器/客户端?或者在您看来,将 REST API 暴露给其他人(邪恶的人)不是什么大不了的事?

以上内容也适用于 WebSockets。我知道 REST API 都很好而且很简洁,但我认为未来在于近乎实时的连接,所以我同样对 WebSockets 感兴趣(当然,通过更高级别的模块,Socket.io、SockJS 等)。

【问题讨论】:

  • 您的客户端是公开的还是受登录机制限制?
  • 客户端部分是公开的(想想网络商店类型的网站),部分是通过身份验证的受限页面。但问题不在于这个。可能我不够清楚,请看my other comment

标签: node.js api rest websocket


【解决方案1】:

有许多解决方案可以保护您的 API,其中许多是开源的。您将使用哪一个实际上取决于您的详细需求。

但为了让您开始,我将提到一个被大型社区接受和支持的解决方案:

查看 JSON Web Token,例如 this Article 中的说明。

基本上,您的客户端从服务器请求一个身份验证令牌,然后将其存储在本地,以便在对您的 API 的每个请求中重复使用它。 另一方面,服务器可以根据需要保护您的 API。这意味着您可能还有一个公共 API,它不需要 HTTP 标头中的令牌。

令牌也可能过期。例如,如果您允许新用户在您的网站上注册一段有限的时间,这将非常方便。

Here is another article 解释事情。

现在讨论您问题的 websocket 部分。是的,您当然也想保护您的服务器端套接字。因此,请注意支持身份验证的库。同样,我认为那里有许多开源库。

提一个:Primus。 Primus 是底层许多套接字库的抽象层,可让您快速更改套接字提供程序。但它也有一个你可以实现的身份验证钩子。

你猜怎么着……你可以用它来检查 JSON Web Token!

希望这能让你开始。

【讨论】:

  • 感谢资源,它对实现用户登录过程非常有用,但这只是部分答案。我已经阅读了有关 JWT 的文章,这绝对是前进的道路,但我要问的是:如何构建一个服务器,其某些 REST API 端点仅限于来自 localhost 机器的调用(服务器),并为注册用户提供 REST API 的其他部分。您的答案涉及下半部分(已经记录了很多)。我希望部分 API 只能由 localhost 在内部访问。这可能吗?
  • 或者我的表述不正确。所以我的静态文件将是访问者查看的客户端,对吗?因此,当我想从数据库中加载包含一些信息的页面时,我会使用 REST API 端点。但是有没有办法让这些端点只能由我的前端访问?也就是说,如果其他人尝试curl 这些端点,他们会得到 404 或 401 或其他东西......虽然不知道这是否可能。想不出办法来限制这些调用。
  • 考虑超级管理员创建管理员的场景。假设管理员登录并且超级管理员从数据库中删除了该用户。当他登录时,他有一个可以发出请求的有效令牌。如果您想验证用户是否存在,您如何解决这种情况?