简体   繁体   中英

How to mix jwt authentication with ACLs

I've been able to implement passport using a JWT strategy, and it works well. My jwt-protected routes look like this...

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

Now I need to restrict access for some things to only logged-in users belonging to some role. I wish I could express that like this:

app.get('/thingThatRequiresLogin/:id', MAGIC, thingThatRequiresLogin.findById);

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

node_acl seems like a good solution, and I understand it up to a point, but then I find this in the doc...

We can protect a resource like this:

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

The middleware will protect the resource named by req.url, pick the user from req.session.userId and check the permission for req.method, so the above would be equivalent to something like this:

How do I mix this with my jwt strategy? My only idea is to forego the node_acl middleware and instead add acl-checking code to my jwt strategy. But that's where I run into trouble. My jwt function looks like this:

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

According to node_acl, I can ask something like this...

acl.isAllowed('jsmith', 'blogs', ['edit','view','delete'])

So can I (should I?) alter my JwtStrategy to say something like...

    if (user && acl.isAllowed(user.username, 'blogs', ['edit','view','delete']) {
        // ...

if so, how will this function know the resource name 'blogs' and the permissions ['edit' etc] ? These are known at the point the route is defined, but I think I need them in the strategy function. Am I going about this all wrong? Can somebody show me the right way?

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

taking a clue from this gist: https://gist.github.com/danwit/e0a7c5ad57c9ce5659d2 and the node_acl doc on npm: https://www.npmjs.com/package/acl#middleware acl.middleware takes three optional arguments: acl.middleware(numPathComponents, userId, permissions)

numPathComponents: 1 //to select thingThatRequiresLogin path

userId: getUserId //getUserId is a function that returns userId

I hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM