Pat*_*ick 21 authorization node.js express
在express.js中基于角色的授权有哪些好的策略?特别是快递资源?
使用Express-resource,没有处理程序,所以我认为有三种选择:
还有其他解决方案吗?
组/基于角色的授权是一种非常古老的方法.是否有更新的访问控制方法?如果没有,基于角色的授权如何应用于node.js?存储组规则关系的位置(使用NoSQL/CouchDB/Redis)?
作为一个例子,结构:
/
/forums
/forums/threads
Run Code Online (Sandbox Code Playgroud)
每个资源都有索引,新建,创建,显示,编辑更新和销毁.有些人可以编辑/删除线程和论坛,有些人不应该.
Lin*_*iel 32
我会说使用快速资源以干净的方式解决这个问题很困难,因为它不允许特定于路由的中间件(至少不是以干净的方式).
我会选择类似的布局作为快递资源模块,但使用普通的旧快递进行路由.像这样的东西:
// 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
Run Code Online (Sandbox Code Playgroud)
更新:目前正在进行关于快递资源中特定于路由的中间件的讨论,例如此处.流行的观点似乎是每个动作都有一个数组,例如:
var forums = {
index: [ requireRole('foo'), function(req, res, next) { ... } ]
};
Run Code Online (Sandbox Code Playgroud)
您可以查看拉取请求,看看是否有任何可以使用的内容.当然,如果你对此感到不舒服,我完全理解它.我很确定未来我们会在快递资源中看到类似的东西.
我能想到的唯一其他解决方案就是Jan Jongboom的答案,即使用快速资源挂载资源,但是将"中间件"附加在"外部",例如:
app.delete('*', requireRole('admin')); // Only admins are allowed to delete anything
app.put('/forums/*', requireRole('moderator')); // Only moderators are allowed to update forums
Run Code Online (Sandbox Code Playgroud)
但我很遗憾,这会在整个地方泄露网址.
Isi*_*dum 27
我一直在研究同样的问题,并且遇到了一些好的模块.我一直专注于可以在这里找到的node-acl包.https://github.com/optimalbits/node_acl.
该软件包似乎以一种非常易懂的方式实现了ACL模式,并提供了将其轻松集成到节点/表达应用程序中的方法.
首先,您需要定义资源,角色和权限.
例如,资源可以是:
/
/forums
/forums/threads
Run Code Online (Sandbox Code Playgroud)
角色可以是
public
admin
user
john
jane
Run Code Online (Sandbox Code Playgroud)
在此示例中,john和jane角色可以映射到实际的用户帐户,但是它们将继承用户角色的所有权限.
资源的权限
或者您的标准CRUD操作.
现在已经定义了这些,我们可以看一下使用node-acl设置acl的样子.这些说明来自文档
导入包
var acl = require('acl');
Run Code Online (Sandbox Code Playgroud)
设置你的后端.我的应用程序正在使用mongodb,但node-acl包确实支持其他存储机制
acl = new acl(new acl.mongodbBackend(dbInstance, prefix));
Run Code Online (Sandbox Code Playgroud)
我的应用程序正在使用mongoose,因此dbInstance将替换为mongoose.connection.db
现在让我们将我们的角色添加到ACL中.在node-acl中,通过赋予角色权限来创建角色.就像用一块石头杀死两只鸟(没有鸟儿实际受到伤害)
acl.allow('admin', ['/', '/forum', '/forum/threads'], '*');
acl.allow('public', ['/', '/forum', '/forum/threads'], 'show');
acl.allow('user', ['/', '/forum', '/forum/threads'], ['create', 'show']);
Run Code Online (Sandbox Code Playgroud)
让我们假设john创建了一个新资源,我们将添加一条新记录,允许john更新和删除该资源.
acl.allow('john', ['/forum/threads/abc123'], ['update', 'delete']);
Run Code Online (Sandbox Code Playgroud)
我的应用程序也使用express,所以我将使用路由中间件方法来检查路由.在我的路由配置中,我会添加该行
在大多数快速配置中,这看起来像pos
app.post('/', acl.middleware(), function(req, res, next) {...});
app.post('/forums', acl.middleware(), function(req, res, next) {...});
app.post('/forums/:forumId', acl.middleware(), function(req, res, next) {...});
app.post('/forums/threads', acl.middleware(), function(req, res, next) {...});
app.post('/forums/threads/:threadId', acl.middleware(), function(req, res, next) {...});
Run Code Online (Sandbox Code Playgroud)
当没有传递参数时,这将检查req.userId中定义的角色是否允许在标识的资源上执行http方法但是路由.
在此示例中,http方法是post,但它将对配置中标识的每个http执行相同的操作.
这提出了关于先前定义的权限的问题.要回答这些问题,我们必须更改权限
到常规
虽然此示例显示了所有硬编码的内容,但更好的做法是为您的权限设置管理界面,以便可以动态创建,读取,更新和删除它们,而无需修改代码.
我喜欢node-acl插件方法,因为它允许使用非常直接和灵活的api进行非常精细的权限角色分配.他们的文档中还有很多内容,我的示例显示我使用的是包.
希望这会有所帮助.
xin*_*nlv 12
Connect-roles非常好,简单,文档也很清晰.
var user = roles;
app.get('/profile/:id', user.can('edit profile'), function (req, res) {
req.render('profile-edit', { id: req.params.id });
})
app.get('/admin', user.is('admin'), function (req, res) {
res.render('admin');
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29144 次 |
| 最近记录: |