Group/rule-based authorization approach in node.js and express.js

后端 未结 6 1632
鱼传尺愫
鱼传尺愫 2021-01-30 00:31

What are good strategies for role-based authorization in express.js? Especially with express-resource?

With Express-resource there are no handlers, so I think there are

6条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-01-30 01:07

    I would say that it's hard to solve this in a clean manner using express-resource, since it doesn't allow for route-specific middleware (at least not in a clean way).

    I would opt for a similar layout as an express-resource module, but route it with plain old express. Something like this:

    // Resource
    var forum = {
      index: // ...
      show: // ...
      create: // ...
      update: // ...
      destroy: // ...
    };
    
    // Middleware
    var requireRole = function(role) {
      return function(req, res, next) {
        if('user' in req.session && req.session.user.role === role)
          next();
        else
          res.send(403);
      }
    };
    
    // Routing
    app.get('/forums', forum.index);
    app.get('/forums/:id', forum.show);
    app.post('/forums', requireRole('moderator'), forum.create); // Only moderators can create forums
    app.delete('/forums/:id', requireRole('admin'), forum.destroy); // Only admins can delete forums
    

    UPDATE: There have been ongoing discussions regarding route-specific middleware in express-resource, e.g. here. The prevailing view seems to be to have an array per action, e.g.:

    var forums = {
      index: [ requireRole('foo'), function(req, res, next) { ... } ]
    };
    

    You could take a look through the pull requests and see if there is anything you could use. I totally understand it, of course, if you don't feel comfortable with that. I'm pretty sure we will see something like this in express-resource in the future.

    The only other solution I can think of is along the lines of Jan Jongboom's answer, which would be to mount the resources with express-resource, but have middleware attached "outside" of that, something like:

    app.delete('*', requireRole('admin')); // Only admins are allowed to delete anything
    app.put('/forums/*', requireRole('moderator')); // Only moderators are allowed to update forums
    

    But I regret that this leaks URLs all over the place.

提交回复
热议问题