如何将jwt身份验证与ACL混合使用

use*_*965 5 javascript acl node.js express passport.js

我已经能够使用JWT战略实施护照,而且效果很好.我受jwt保护的路线看起来像这样......

app.get('/thingThatRequiresLogin/:id', passport.authenticate('jwt', { session: false }), thingThatRequiresLogin.findById);
Run Code Online (Sandbox Code Playgroud)

现在我需要将某些内容的访问限制为仅属于某个角色的登录用户.我希望我能像这样表达:

app.get('/thingThatRequiresLogin/:id', MAGIC, thingThatRequiresLogin.findById);
Run Code Online (Sandbox Code Playgroud)

哪里 MAGIC = require logged-in users, but only those with role x or y

node_acl似乎是一个很好的解决方案,我理解它到了一定程度,但后来我在doc中找到了这个...

我们可以保护这样的资源:

app.put('/blogs/:id', acl.middleware(), function(req, res, next){…}
Run Code Online (Sandbox Code Playgroud)

中间件将保护req.url命名的资源,从req.session.userId中选择用户并检查req.method的权限,因此上述内容将等同于:

我如何将其与我的jwt策略混合使用?我唯一的想法是放弃node_acl middleware,而是将acl检查代码添加到我的jwt策略中.但那就是我遇到麻烦的地方.我的jwt函数看起来像这样:

passport.use(new JwtStrategy(jwtOptions, function(jwt_payload, done) {
    User.findOne({id: jwt_payload.sub}, function(err, user) {
        if (err) {
            return done(err, false);
        }
        if (user) {
            done(null, user);
        } else {
            done(null, false);
            // or you could create a new account
        }
    });
}));
Run Code Online (Sandbox Code Playgroud)

根据node_acl,我可以问这样的事情......

acl.isAllowed('jsmith', 'blogs', ['edit','view','delete'])
Run Code Online (Sandbox Code Playgroud)

我也可以(我应该吗?)改变我的JwtStrategy来说出类似......

    if (user && acl.isAllowed(user.username, 'blogs', ['edit','view','delete']) {
        // ...
Run Code Online (Sandbox Code Playgroud)

如果是这样,该函数将如何知道资源名称'blogs'和权限['edit' etc]?这些在路由定义时已知,但我认为我需要在策略功能中使用它们.我错了吗?有人能告诉我正确的方法吗?

小智 6

app.get('/thingThatRequiresLogin/:id', 
  [
     passport.authenticate('jwt', { session: false }), 
     acl.middleware( 1, getUserId )
  ], 
  thingThatRequiresLogin.findById);
Run Code Online (Sandbox Code Playgroud)

从这个要点中获取线索:https: //gist.github.com/danwit/e0a7c5ad57c9ce5659d2和npm上的node_acl doc:https: //www.npmjs.com/package/acl#middleware acl.middleware有三个可选参数: acl.middleware(numPathComponents,userId,permissions)

numPathComponents:1 //选择thingThatRequiresLogin路径

userId:getUserId // getUserId是一个返回userId的函数

我希望这有帮助