如何在 Node 中使用 Passport.js 模拟其他用户



使用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 服务器将拒绝它。

解决这个问题的方法是编写自己的护照身份验证策略,显然不会这样做,但我假设您在这里谈论的是使用内置策略。

最新更新