PassportJS - 是否可以为其他用户更改 req.user?

PassportJS - Is it possible to change req.user for another user?

在我的应用程序中,我实现了更改用户权限、等级等的功能。效果很好,如果我更新自己的权限,我可以立即看到更改,因为我可以更新 req.user 对象通过 req.login()。问题是,当我更新另一个用户的权限时,它在数据库中更新得很好,但是用户将不得不重新登录才能看到他们的权限更改,因为 req.user 仍然认为他们没有权限。当然,如果他们没有登录,这很好,但如果他们登录了,我希望尽可能立即为他们反映更改。

所以我想知道是否有办法更新另一个用户 req.user 对象,以便他们可以立即看到他们的权限更改,而无需注销并重新登录?

或者在返回之前注销并登录该用户的方法?

您可以尝试删除session,或者重新生成sessionID。但这将迫使该用户重新登录。

如果您的会话存储在 mongodb 中。然后您可以按名称 app_sessions 检查集合,它有一个按名称 userId.

的字段

在 Express 会话中有一个名为商店的模块。它提供了很多 API 来通过 sessionID 查找会话。但不幸的是,没有 API 可以通过用户 ID 查找会话。

所以如果你想使用 session store API 那么你可以调用 store.all ,这将提供所有会话。但这实在是太残忍的方法了。因为我不知道它可能持有多少数据。

由于权限在您自己的数据库中,因此当然可以,但是如何操作取决于您的应用程序。

假设您正在使用会话,存储在 req.user 中的对象将通过使用您随 passport.deserializeUser 提供的函数为每个 HTTP 请求单独加载。通常,您会将用户 ID 存储到 passport.serializeUser 中的会话,然后使用 deserializeUser 中的 ID 从数据库中检索用户。因此,无论何时在后端处理请求,您通常都会在 req.user 中获得最新信息,包括权限。当然,您的前端还需要以某种方式获得新权限并自行调整(例如,如果您向用户添加管理员权限,您可能希望他们在 UI 中看到管理员选项)。

您当然可以只将整个用户对象传递给会话存储并跳过每个请求的一次数据库调用,即。使用这些:

passport.serializeUser(function(user, cb) { cb(null, user); });
passport.deserializeUser(function(user, cb) { cb(null, user); });

用于会话处理。如果您这样做,则数据库更改不会反映在 req.user 对象上。如果用户更新了他们自己的信息,你可以只调用 req.logIn(...),但你不能为其他用户调用。你可以解决这个问题 - 例如。通过 websocket 通知有问题的用户,并让他们的浏览器调用一个路由,该路由使用最新的用户对象调用 req.logIn,或者深入会话存储并直接在那里操作数据。

或者,由于强制注销是一个选项,您可以按照 enRaisers 的回答并从会话存储中找到用户会话并将它们全部删除,这实际上是从后端注销用户。您可以通过 API 浏览会话,或者如果您将数据库(例如 connect-mongoconnect-redis)用于会话存储,您还可以打开另一个到同一数据库的连接并使用正常的搜索和销毁方法。同样,您仍然需要自己以某种方式在前端处理注销。