我的应用程序需要基于请求用户和请求的资源之间的关系进行授权。访问详细信息封装在要请求的资源中。
让我们走路线PATCH /articles/1
:文章有一个作者/所有者和一系列编辑,他们都有权更新文章。请求用户经过身份验证,可以是作者或编辑之一。否则,应拒绝访问。
-
我有两个想法:
中间件中的授权:
这意味着中间件在控制器可以完成资源聚合之前就已经需要资源了。但是,有时(例如,当使用MongoDB聚合框架时)控制器将无法重用该资源,并且需要另一次往返数据库。
控制器中的授权:
一旦资源可用/聚合,就可以在控制器中执行授权。但是这会将这部分授权与身份验证和基于角色的访问控制分开,我已经将其作为中间件。
我个人认为中间件方法更有意义,但数据库将由另一个PaaS托管,即使在同一个数据中心内,也可能存在一些延迟。
如果请求相关资源(例如评论)怎么办?这将涉及一些特定的逻辑,来自对存储访问细节的文章的评论。并且会使我的auth中间件更不通用。
-
还有其他选择吗?
-
该应用程序使用Koa,但这些概念可能适用于所有其他支持中间件的框架,例如Express或其他。
请注意,我并未询问connect-roles
提供的身份验证或基于角色的经典访问。
答案 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年是合理的,而不是在发布日。