【问题标题】:Authorize every request vs delete user session from cache授权每个请求与从缓存中删除用户会话
【发布时间】:2020-09-30 16:35:55
【问题描述】:

我正在运行一个带有 PostgreSQL 数据库的 NodeJS express 应用程序。我在 express 中使用 node-cache 模块作为会话管理的存储。

该应用程序有一个用户管理方案,该方案由两种类型的用户组成,普通用户和管理员。管理员可以执行普通用户可以执行的所有任务。除此之外,管理员可以在应用程序中添加/删除用户,还可以向/从用户授予/撤销管理员权限。所以我的问题来了:

如果管理员在用户 X 仍登录时从工具中删除用户 X,那么在用户 X 向服务器发送下一个请求时,他必须自动注销。同样,如果管理员在用户 Y 仍处于登录状态时撤销了用户 Y 的管理员权限,那么在下次访问服务器时,用户 Y 应该会自动注销。

经过一番研究,我想出了两种实现方式:

1) 授权每个请求 - 即编写一个中间件来查询数据库并检查用户是否仍然具有工具访问权限。但是这种方法会为每个请求增加一个额外的数据库命中的开销。我认为这是一个很大的开销,因为在我的应用程序中用户不会被频繁删除,而且用户在已经登录时被删除的可能性也很小。

2) 不要授权每个请求。相反,当用户的工具访问权限被删除时,从缓存中删除该用户的会话(如果有)。因此,当该用户发送请求时,他将被注销,因为他的会话不再存在。但是,这样做并不是那么简单,因为节点缓存(甚至 Redis)没有任何“按值删除”功能。为此,我必须搜索缓存中的所有键,找到值与需要删除会话的用户的 userID 相同的值,然后删除这些会话。

我想知道哪种方法更好更有效,或者是否有第三种更好的方法。

【问题讨论】:

  • 欢迎来到 StackOverflow!请更详细地描述您的问题,并提供更多见解,例如解释您想要完成的实际任务,添加错误代码 sn-p 以及您实际尝试过的所有解决方案以消除该问题。在粘贴之前记下添加相应的标签并格式化您的代码。有关更多详细信息,请访问 StackOverflow 的指南,包括 stackoverflow.com/help/how-to-ask。

标签: node.js express session express-session role-based-access-control


【解决方案1】:

1)我不建议任何人采用第一种方法。当我扩大规模时,每个请求的数据库命中都会成为重大开销。此外,即使我没有进行任何数据库操作 (CRUD) 只是请求某些资源(例如网页),它也会让我查询数据库。

2)与第一种方法相比,我的第二种方法似乎要好一些。但是,按值搜索的复杂度为 O(n)。所以当我扩大规模时,这将需要更多时间。这种方法也引入了竞争条件。想象一个场景,我通过更新数据库来删除用户的访问权限,然后继续删除缓存中的用户会话。如果用户数量很大,那么用户很可能会在访问被删除之后但在其会话无效之前执行一些未经授权的操作。

我已经为这个问题想出了更多的解决方案:

3) 存储用户 ID 作为键,会话 ID 作为值。但是,为此我必须确保我的用户 ID 是唯一的。这也有一个缺点,即在任何给定时间,用户只能激活一个会话。前任。如果用户已登录,但他从另一台机器/浏览器再次登录,那么他所有的旧会话都将失效。

4) 通过将用户 ID 附加到会话 ID 来创建自定义会话 ID。然后我可以通过指定模式来搜索键。此功能在 Redis 中可用,但不建议在生产代码中使用。此功能在我正在使用的节点缓存模块中不可用。尽管如此,它的复杂度仍然是 O(n)。

5) 使用 Redis 集来存储用户的所有会话 ID 与他的用户 ID。但是,我仍然必须存储会话 ID 与用户 ID 来维护会话的各个生命周期。删除用户访问权限后,我可以使用该集合检索所有用户会话 ID,并使用它们从缓存中删除所有会话。缺点是每次用户创建新会话/注销时,都应该更新集合和哈希。此外,该集合应在会话到期时更新。

6) 在数据库中存储一个字段,指示用户是否已登录,以及一个包含其活动会话列表的附加字段。这样我可以检查用户是否登录,如果是,则检索他的所有会话 ID,然后从缓存中删除它们。类似于方法5。

【讨论】:

  • 我遇到了同样的问题,很惊讶解决这个问题的资源很少,因为我认为这是一个相当普遍的问题。
猜你喜欢
  • 1970-01-01
  • 2015-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-16
  • 1970-01-01
  • 2012-12-22
  • 2016-12-12
相关资源
最近更新 更多