我想使用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策略。看起来像是矫枉过正。
其他选项是在用户通过身份验证后验证每个路由中的访问/组。但如果可能的话,我宁愿在中间件中这样做。
由于
答案 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) {
});