Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js PassportJS-是否可以将req.user更改为其他用户?_Node.js_Express_Passport.js - Fatal编程技术网

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

Node.js PassportJS-是否可以将req.user更改为其他用户?,node.js,express,passport.js,Node.js,Express,Passport.js,在我的应用程序中,我实现了更改用户权限、排名等的功能。它非常有效,如果我更新自己的权限,我可以立即看到更改,因为我可以通过req.login()更新req.user对象。问题是,当我更新另一个用户的权限时,它会在数据库中正常更新,但用户必须重新登录才能看到他们的权限更改,因为req.user仍然认为他们没有权限。当然,如果他们没有登录,这是可以的,但是如果他们登录了,我希望如果可能的话,这些更改能够立即反映出来 所以我想知道是否有一种方法可以更新另一个用户req.user对象,这样他们就可以立即

在我的应用程序中,我实现了更改用户权限、排名等的功能。它非常有效,如果我更新自己的权限,我可以立即看到更改,因为我可以通过
req.login()
更新req.user对象。问题是,当我更新另一个用户的权限时,它会在数据库中正常更新,但用户必须重新登录才能看到他们的权限更改,因为
req.user
仍然认为他们没有权限。当然,如果他们没有登录,这是可以的,但是如果他们登录了,我希望如果可能的话,这些更改能够立即反映出来

所以我想知道是否有一种方法可以更新另一个用户
req.user
对象,这样他们就可以立即看到自己的权限更改,而无需注销和重新登录


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

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

如果您的会话存储在mongodb中。然后,您可以按名称应用程序会话检查集合,并且它有一个按名称用户ID的字段

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


因此,如果要使用,可以调用store.all,这将提供所有会话。但这确实是一种残忍的方法。因为我不知道它可能保存了多少数据。

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

如果您正在使用会话,则存储在
req.user
中的对象将使用您随
passport.deserializeUser
提供的函数为每个HTTP请求分别加载。通常,您会将用户ID存储到会话中的
passport.serializeUser
,然后使用
反序列化user
中的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 mongo
connect redis
)进行会话存储,您还可以打开到同一数据库的另一个连接,并使用正常的搜索和销毁方法。同样,您仍然需要自己处理前端的注销。

我确实使用Mongodb,但其中没有包含app_会话的集合。另外,从我所知道的,它看起来像注销用户将删除会话,这对我来说很好,但我如何才能做到这一点,另一个用户?感谢您的回复。因此,我更改了反序列化函数以从数据库中获取用户,现在
req.user
将在用户刷新页面后更新。我越想它,我就越觉得问题的根源在于我正在根据
req.user
验证权限,以避免每次有人做基于权限的事情时都运行db查找(这种情况经常发生)。作为一个比我更有经验的人,您认为使用db查找来验证用户权限,而不是一直更新
req.user
是否合适?这并不是一个庞大的应用程序。一般来说,我会说,跳过一个查询,其中一个项目是通过它的ID获取的,这是一个微观优化,在
反序列化用户中命中数据库在我的项目中从来都不是一个问题。在几乎所有的数据库中,按唯一id查询可能是最快的查询方法,通常,如果您不断地请求同一行,数据库会做一些事情来加快速度。仅供参考,我从我的14M行Postgres数据库中按ID查询了一行,第一个查询是65ms。具有相同ID的第二个查询为0.063ms.True。谢谢你的建议!最后,我将passport反序列化方法更改为:
passport.serializeUser(函数(user,done){done(null,user.id);});passport.deserializeUser(函数(id,done){User.findById(id,函数(err,User){done(err,User);});})可使
req.user
保持最新。在前端(在我的例子中是Angular 1),我还通过调用返回
req.user
的路由,在每次路由更改时更新用户,以保持视图的更新。希望这能帮助其他人:)