使用中间件进行授权

时间:2014-04-16 19:29:02

标签: express authorization middleware koa

我的应用程序需要基于请求用户和请求的资源之间的关系进行授权。访问详细信息封装在要请求的资源中。

让我们走路线PATCH /articles/1:文章有一个作者/所有者和一系列编辑,他们都有权更新文章。请求用户经过身份验证,可以是作者或编辑之一。否则,应拒绝访问。

-

我有两个想法:

  1. 中间件中的授权:
    这意味着中间件在控制器可以完成资源聚合之前就已经需要资源了。但是,有时(例如,当使用MongoDB聚合框架时)控制器将无法重用该资源,并且需要另一次往返数据库。

  2. 控制器中的授权:
    一旦资源可用/聚合,就可以在控制器中执行授权。但是这会将这部分授权与身份验证和基于角色的访问控制分开,我已经将其作为中间件。

  3. 我个人认为中间件方法更有意义,但数据库将由另一个PaaS托管,即使在同一个数据中心内,也可能存在一些延迟。

    如果请求相关资源(例如评论)怎么办?这将涉及一些特定的逻辑,来自对存储访问细节的文章的评论。并且会使我的auth中间件更不通用。

    -

    还有其他选择吗?

    -

    该应用程序使用Koa,但这些概念可能适用于所有其他支持中间件的框架,例如Express或其他。

    请注意,我并未询问connect-roles提供的身份验证或基于角色的经典访问。

1 个答案:

答案 0 :(得分:0)

我的正常模式是使用路由参数从数据库中获取资源,例如:

app.param("articleId", function (req, res, next, paramValue) {
  var _id;
  try {
    _id = new ObjectID(paramValue);
  } catch (error) {
    res.status(400).send('Invalid ID');
    return;
  }
  Article.findById(_id, function(error, doc){
    if (error) {
      next(error);
      return;
    }
    if (doc) {
      req.article = doc;
      next();
      return;
    }
    res.send(404);
  });
});

然后我使用中间件进行授权,但可以假设req.article已从数据库中加载。

这是一个很好的默认模式,我认为您应该使用它一段时间并在进行任何性能优化之前习惯它,但是当您确实有足够的流量来选择不太通用的模式时,请选择它。请记住,通常在启动/项目的第2年或第3年是合理的,而不是在发布日。