我使用的是passport-jwt。我正在尝试在我的系统中实现一个acl模式。我的系统中有一些不同的角色。我想控制他们对某些资源的访问权限。
我认为在基于令牌的身份验证中执行此操作的常用方法是为express.js编写中间件,该中间件将验证令牌并向“req.user”添加“角色”字段。然后将另一个中间件安装到每个路由,指定哪些角色可以访问它们。 所以我的问题是,如何将这种方法与passport-jwt结合起来。
加: 使用passport-jwt策略的常用方法是:
app.get('/myapi', passport.authenticate('jwt', {session: false}),
function(req, res, next){ ...})
我认为基于令牌的身份验证的常见方式是:
app.use(function(req, res, next){
token = extractToken(req)
jwt.verify(token, key, function(err, decoded) {
if (err) {
return res.send(err);
} else {
users.findOne({userId: decoded.userId}, function(err, user){
if(!user) res.send('unknown')
else{
req.user = user //in which include a role field.
// for example: user.role = 'user' | 'manager'
}
})
}
});
})
and at every route:
function checkRole(roles){
return function (req, res, next) {
if (req.session.user && roles.includes(req.user.role)) {
next();
} else {
res.send(403);
}
}
}
app.get('/myapi', checkRole(['user']), function(req, res){
....
})
答案 0 :(得分:1)
我弄清楚自己。 我写了一个中间件来一起做这些事情:
/*middleware/acl.js */
export function checkRoleWithPassport(roles, passport, strategy, opts){
return function(req, res, next){
passport.authenticate(strategy, opts, function(err, user, info){
if(err) res.status(403).send('forbidden')
else if(!user) res.status(403).send('forbidden')
else{
if(roles.length == 0)
next()
else if(roles.includes(user.role))
next()
else
res.status(403).send('forbidden')
}
})(req, res, next)
}
}
/* route/index.js */
app.get('/myapi', checkRoleWithPassport(['manager'], passport,
'jwt', {session, false}), function(req, res){
...
}) // this should only allow the 'manager' to access /myapi