验证Passport.js中的访问/组

时间:2013-03-30 13:34:33

标签: 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);
    });
  }
));

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

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

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

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

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

由于

1 个答案:

答案 0 :(得分:53)

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

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) {
    ...
  });

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

另一种选择可能是connect-roles,但我不知道它与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) {
});