验证Passport.js中的访问/组

los*_*ion 30 node.js passport.js

我想使用passport.js来验证当用户点击某些端点时,他们不仅拥有正确的密码,而且是特定组的成员或具有特定访问权限.

为简单起见,如果我有访问级别的USER和ADMIN.

我可以使用护照来验证密码:

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function(err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));
Run Code Online (Sandbox Code Playgroud)

然后使用路线我可以确保用户通过身份验证:

app.get('/api/users',
  passport.authenticate('local'),
  function(req, res) {
    res.json({ ... });
  });
Run Code Online (Sandbox Code Playgroud)

但是,让我们说你需要有一个ADMIN访问来命中/ api/users'.我需要编写自己的策略吗?IE我需要有本地用户和本地管理员策略,并在每个验证适当的访问级别?

我想我可以很容易地做到这一点,但是当我需要我的网站有不同的auth方法(可能有时使用oauth)时会出现问题,我需要为每个方法编写自定义*-user,*-admin策略.似乎有点矫枉过正.

其他选项是在用户通过身份验证后验证每条路由中的访问/组.但如果可能的话,我宁愿在中间件中这样做.

谢谢

rob*_*lep 54

您可以创建一个检查组的简单中间件:

var needsGroup = function(group) {
  return function(req, res, next) {
    if (req.user && req.user.group === group)
      next();
    else
      res.send(401, 'Unauthorized');
  };
};

app.get('/api/users', 
  passport.authenticate('local'),
  needsGroup('admin'), 
  function(req, res) {
    ...
  });
Run Code Online (Sandbox Code Playgroud)

这假设存储的对象req.user具有属性group.这个对象是从策略实现中传递的对象deserializeUser.

另一种选择可能是连接角色,但我不知道它与Passport的集成程度如何.

编辑:您还可以组合Passport和组检查中间件:

var needsGroup = function(group) {
  return [
    passport.authenticate('local'),
    function(req, res, next) {
      if (req.user && req.user.group === group)
        next();
      else
        res.send(401, 'Unauthorized');
    }
  ];
};

app.get('/api/users', needsGroup('admin'), function(req, res) {
});
Run Code Online (Sandbox Code Playgroud)

  • 是的,它是:'app.VERB(路径,[回调...],回调)'.对不起,我错过了,谢谢你的回答如此友善! (2认同)