小编典典

如何使用 node.js 实现安全的 REST API

all

我开始用 node.js、express 和 mongodb 计划一个 REST API。API
为网站(公共和私人区域)提供数据,以后可能还会为移动应用程序提供数据。前端将使用 AngularJS 开发。

几天来,我阅读了很多关于保护 REST API 的内容,但我没有找到最终的解决方案。据我了解是使用HTTPS来提供基本的安全性。但是我如何在这些用例中保护
API:

  • 仅允许网站/应用程序的访问者/用户获取网站/应用程序公共区域的数据

  • 仅允许经过身份验证和授权的用户获取私有区域的数据(并且仅允许用户授予权限的数据)

目前我考虑只允许具有活动会话的用户使用 API。为了授权用户,我将使用护照并获得许可,我需要为自己实现一些东西。一切都在 HTTPS 之上。

有人可以提供一些最佳实践或经验吗?我的“架构”有缺陷吗?


阅读 60

收藏
2022-06-22

共1个答案

小编典典

我遇到了你描述的同样的问题。我正在构建的网站可以通过手机和浏览器访问,因此我需要一个 api
来允许用户注册、登录和执行某些特定任务。此外,我需要支持可伸缩性,即在不同的进程/机器上运行相同的代码。

因为用户可以创建资源(又名 POST/PUT 操作),所以您需要保护您的 api。您可以使用
oauth,也可以构建自己的解决方案,但请记住,如果密码真的很容易发现,所有解决方案都可能被破解。基本思想是使用用户名、密码和令牌(也称为
apitoken)对用户进行身份验证。这个 apitoken 可以使用node-uuid生成,密码可以使用pbkdf2散列

然后,您需要将会话保存在某处。如果您将其保存在内存中的普通对象中,如果您终止服务器并再次重新启动它,则会话将被破坏。此外,这是不可扩展的。如果您使用
haproxy
在机器之间进行负载平衡,或者您只是使用工作人员,则此会话状态将存储在单个进程中,因此如果同一用户被重定向到另一个进程/机器,则需要再次进行身份验证。因此,您需要将会话存储在一个公共位置。这通常使用
redis 完成。

当用户通过身份验证(用户名+密码+apitoken)时,会为会话生成另一个令牌,即 accesstoken。同样,使用 node-
uuid。向用户发送访问令牌和用户 ID。userid(key)和accesstoken(value)存储在redis中,有过期时间,比如1h。

现在,每次用户使用 REST API 执行任何操作时,都需要发送用户 ID 和访问令牌。

如果您允许用户使用 rest api 注册,您需要创建一个带有 admin apitoken
的管理员帐户并将其存储在移动应用程序中(加密用户名+密码+apitoken),因为新用户不会有 apitoken他们注册了。

网络也使用这个 api,但你不需要使用 apitokens。您可以将 express 与 redis 存储一起使用,或者使用上述相同的技术,但绕过
apitoken 检查并在 cookie 中向用户返回 userid+accesstoken。

如果您有私人区域,则在进行身份验证时将用户名与允许的用户进行比较。您还可以将角色应用于用户。

概括:

序列图

没有 apitoken 的替代方法是使用 HTTPS 并在 Authorization 标头中发送用户名和密码,并将用户名缓存在 redis 中。

2022-06-22