如何在 Node 中使用 Passport.js 模拟另一个用户?

How can I impersonate another user with Passport.js in Node?

在 Node 中使用 Passport.js,有没有办法让一个用户冒充另一个用户?例如。作为应用程序的管理员,我希望能够以另一个用户的身份登录,而不知道他们的密码。

最简单的是,如果我可以更改序列化的用户数据(用户 ID),我会很满意,因此当调用 deserializeUser 时,它只会假设备用用户的身份。我已经尝试替换 req._passport.session.user 处的值和 req.session.passport.user 处的值,但最终结果是我的会话似乎变得无效并且 Passport 将我注销。

你的问题的答案基本上:没有。原因是:会话库 99% 的时间都在对 cookie 进行签名,因此如果您篡改数据,Web 服务器将拒绝它。

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

Passport 提供了一种 req.logIn 方法,以防您想手动进行身份验证。您可以使用它来登录任何用户,即使不考虑身份验证。

以下是您的使用方法。让管理员正常登录,设置 isAdmin 标志。

然后在您的登录路径 passport.authenticate 之前放置一个中间件。如果 当前 登录用户 isAdmin.

,这将仅根据用户名登录 new 用户
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);
    }
);

我还有另一种模仿方式,因为:

  • 我不想弄乱 authentication/passport 的内部结构,比如 session storage / logIn / etc. 你必须非常了解它们 而且它们很容易发生变化,所以我认为这不是 我。
  • 此外,我仍然希望能够判断操作是否来自 超级用户(模拟)或普通用户(未模拟)。

我做的是:

  • 为具有超级管理员角色的用户设置一个路由来模拟,例如 /superadmin/impersonate?username=normaluser1 设置 req.user.impersonated.userid = normaluser1.userid

  • 然后我有一个中间件,它检查用户是否是超级管理员并被模拟:

    if (req.user.isAdmin && req.user.impersonated) { req.user.userid = req.user.impersonated.userid; }

另外,我发现 this 是一篇关于用户模拟的好文章。类似于我的方法,对于构建类似的东西很有帮助。