Mongodb 基于NoSQL文档库的RBAC建模策略
我正准备在我的应用程序中实现的精简版本,我正在考虑如何/如何在我的应用程序中建模,它恰好是mongodb,mongoose.js是我的“便利库”。但是这个问题应该适用于任何文档存储 考虑到复制与性能等竞争因素,在使用文档存储时,在使用嵌入式对象与引用之间做出选择似乎是一个相当常见的挑战。我试图使RBAC尽可能简单,不要对嵌套的集合/引用ID太过疯狂,这意味着大量循环,过度使用mongoose的填充等等 问题: 我已经倾向于为用户、权限和角色设置集合;但是,对操作和资源进行建模,或者仅仅对这些操作和资源使用key/vals,这有意义吗 请参阅下面的代码示例,或者这将有助于解释问题。注意,这根本不是我想要实现的方式,只是一种检查关系的方式 然后我可以进行如下更改,如删除等(假设我已经在调用点从mongo检索到一个角色对象):Mongodb 基于NoSQL文档库的RBAC建模策略,mongodb,mongoose,nosql,Mongodb,Mongoose,Nosql,我正准备在我的应用程序中实现的精简版本,我正在考虑如何/如何在我的应用程序中建模,它恰好是mongodb,mongoose.js是我的“便利库”。但是这个问题应该适用于任何文档存储 考虑到复制与性能等竞争因素,在使用文档存储时,在使用嵌入式对象与引用之间做出选择似乎是一个相当常见的挑战。我试图使RBAC尽可能简单,不要对嵌套的集合/引用ID太过疯狂,这意味着大量循环,过度使用mongoose的填充等等 问题: 我已经倾向于为用户、权限和角色设置集合;但是,对操作和资源进行建模,或者仅仅对这些操作
函数removePerm(角色、操作、资源){
如果(!role | | |!role.perms | |!role.perms[op]){
log(“未定义的内容!”);
返回false;
}
var perm=role.perms[op];
对于(var i=0,len=perm.length;i您的设计几乎完全取决于应用程序的行为。根据您在此处提供的信息,我建议将数据保留在键/值中,而不是数据库中——CRUD操作不会更改,因此没有理由将其放在数据库中。“资源”不是类您已经将其内置到代码中,因此也不需要在数据库中复制它。我最近使用了mongoosejs,其用户/角色/权限是Drywall.js所需的-实际权限是基于键/值的。它们可以由组共享,也可以在管理员级别上被粒度覆盖
虽然这不完全是RBAC,但我希望回顾另一种方法可以帮助您更接近实现目标
项目概况:
猫鼬模式:
具体来看:
- /schema/User.js
- /schema/Admin.js
- /schema/AdminGroup.js
- /schema/Account.js
我很想看看你有什么想法。但是如果我想为管理员提供一种在角色中更改权限的方法,会发生什么情况。因此,看看我的示例,用户希望允许“编写者”为了能够对用户进行读取访问。他们必须能够访问代码本身。这就是我希望存储这些代码的原因。因此,在这种情况下,您的界面允许他们选择复选框等,并且该应用程序的角色现在已更改。抱歉,我没有明确说明这一点,并将编辑我的帖子。不,没关系,我理解您的意图你在编辑中所做的一切都会很好。
/*
Imagine this being used in a CMS ;)
User: have a role property (e.g. role:"admin" or role:"writer")
Operation: Create,Read,Update,Delete,etc.
Resource: Page,Post,User, etc.
* For simplicity, we can represent operations and resource with simple strings.
Permission: A permission is an allowable "Operation" on a "Resource"
Role: A Role is just an abstraction of a set of possible "Permissions"
*/
// I could see this as a Permission model in mongo
var adminPerms = {
create: ['pages','posts', 'users'],
update: ['posts','pages','users'],
update_others: ['posts','pages'],
delete: ['posts','pages','users'],
read:['pages','posts','users']
};
// I could see this as a Role model in mongo
var admin = {
perms: adminPerms
};
var writerPerms = {
create: ['pages','posts'],
update: ['pages','posts'],
update_others: [],
delete: [],
read:['pages','posts']
};
var writer = {
perms: writerPerms
};
// Now we can just see if that user's perms has the operation on resource defined
function hasPerms(user, operation, resource) {
var i, len, op;
if(!user || !user.role || !operation || !resource) return false;
if(typeof rolemap[user.role] !== 'undefined' &&
typeof rolemap[user.role]['perms'] !== 'undefined' &&
typeof rolemap[user.role]['perms'][operation] !== 'undefined') {
op = rolemap[user.role]['perms'][operation];
for(i=0, len=op.length; i<len; i++) {
if(op[i] === resource) {
return true;
}
}
}
return false;
}
var rolemap = {"admin":admin, "writer":writer}
var user_admin = {name:'Rob Levin', role:'admin'}
var user_jack = {name:'Jack Black', role:'writer'}
hasPerms(user_jack, 'create', 'users')
// false
hasPerms(user_admin, 'create', 'users')
// true
hasPerms(user_admin, 'update_others', 'posts')
// true
hasPerms(user_jack, 'update_others', 'posts')
// false
db.role.find({name:'writer'}).pretty()
{
"_id" : ObjectId("4f4c2a510785b51c7b11bc45"),
"name" : "writer",
"perms" : {
"create" : [
"posts",
"pages"
],
"update" : [
"posts",
"pages"
],
"update_others" : [ ],
"delete" : [ ],
"read" : [
"posts",
"pages"
]
}
}
function removePerm(role, op, resource) {
if(!role || !role.perms || !role.perms[op]) {
console.log("Something not defined!");
return false;
}
var perm = role.perms[op];
for(var i=0, len=perm.length; i<len; i++) {
if(perm[i] === resource) {
perm.splice(i,1);
break;
}
}
}