使用Passport.js在Node中,有没有办法允许一个用户模拟另一个用户? 例如。作为应用程序中的管理员,我希望能够以其他用户身份登录,而无需知道其密码。
最简单的是,如果我能更改序列化的用户数据(用户 ID),这样当调用deserializeUser
时,它只会假定备用用户的身份,我会感到满意。 我尝试替换 req._passport.session.user
的值和 req.session.passport.user
的值,但最终效果只是我的会话似乎变得无效并且 Passport 将我注销。
Passport 提供了一种req.logIn
方法,以防您想手动进行身份验证。即使身份验证如何,您也可以使用它来登录任何用户。
以下是使用它的方法。让管理员正常登录,谁将设置一个isAdmin
标志。
然后在登录路由中passport.authenticate
之前放置一个中间件。如果当前登录的用户isAdmin
,这将仅根据新用户的用户名登录新用户。
app.post('/login',
function forceLogin(req, res, next) {
if (!req.user.isAdmin) return next(); // skip if not admin
User.findOne({
username: req.body.username // < entered username
}, function(err, user) {
// no checking for password
req.logIn(user);
res.redirect('/users/' + user.username);
});
},
passport.authenticate('local'),
function(req, res) {
res.redirect('/users/' + req.user.username);
}
);
我有另一种模拟方式,因为:
- 我不想弄乱身份验证/护照的内部结构,例如会话存储/登录/等你必须非常了解它们而且它们也容易改变,所以我想说这不是一个选择我。
- 另外,我希望仍然能够判断操作是否来自超级用户(模拟)或普通用户(未模拟)。
我所做的是:
-
为具有超级管理员角色的用户提供要模拟的路由,例如设置
req.user.impersonated.userid = normaluser1.userid
的路由/superadmin/impersonate?username=normaluser1
-
然后我有一个中间件,它检查用户是否是超级管理员并被模拟:
if (req.user.isAdmin && req.user.impersonated) { req.user.userid = req.user.impersonated.userid;}
另外,我发现这是一篇关于用户模拟的好文章。与我的方法类似,并且有利于构建类似事物的灵感。
你的问题的答案基本上是:不。原因是:99% 的时间正在使用的会话库正在对 cookie 进行签名,因此如果您篡改数据,Web 服务器将拒绝它。
解决这个问题的方法是编写自己的护照身份验证策略,显然不会这样做,但我假设您在这里谈论的是使用内置策略。