MongoDB + Node JS +基于angular色的访问控制(RBAC)
我目前正在学习MEAN堆栈,开发一个简单的TODO的应用程序,并希望为此实现基于angular色的访问控制(RBAC)。 我如何在MongoDB上设置angular色和权限?
我想要3个angular色(angular色可能看起来很有趣,但这纯粹是为了学习):
- 神
- 超级英雄
- 人
上帝 – 类似于超级pipe理员,可以在应用程序中做任何事情。 C,R,U,D权限也适用于TODO和其他用户。 可以创build一个TODO,并将其分配给任何超级英雄或人直接。 在任何时间点更新或删除TODO或用户。
超级英雄 – 类似于pipe理员,超级力量做任何事情在他的个人数据 – C,R,U,D TODO的。 无法创build任何用户。 只能阅读和添加由GOD&TODO分配给他/她的TODO的评论。
MAN – 只能读取和添加评论给TODO分配给他/她的人。
把它们加起来 :
GOD - C,R,U,D [Global Level] SUPER HERO - C,R,U,D [Private] + R,U [Assigned to him] MAN - R,U [Assigned to him]
我明白,我需要有USERS&ROLES系列。 在哪里ROLES inturn应该有权限等我怎么把他们所有?
我喜欢给angular色的名字 – 上帝,超级英雄和人 ,容易理解。
由于您正在使用MEAN堆栈,并且许多路由validation发生在node
,所以我宁愿保持angular色表格简单。
angular色:
{ _id : 1, name : GOD, golbalPerms : true }, { _id : 2, name : SUPER HERO, privatePerms : true }, { _id : 3, name : MAN }
用户:
{ _id : 111, name : Jesus, roleId : 1 }, { _id : 222, name : BatMan, roleId : 2 }, { _id : 333, name : Jack, roleId : 3 }
当用户login并将user
对象发送回客户端时,请确保将roleId
replace为DB中对应的role
对象。
来到节点JS上的代码:
通过完全理解你的用例,我们可以将它们分成以下几种方法 –
-
创build用户
-
CreateTodo
-
DeleteTodo
-
ReadTodo
- UpdateTodo
-
CommentTodo
-
AssignTodo
让我们一步一步, CreateUser 。
路由代码片段:
app.all('/users', users.requiresLogin); // Users Routes app.route('/users') .post(users.hasPerms('globalPerms'), users.create);
在您的Controller中,您可以基于input的globalPerms
进行validation,如果validation允许通过调用next()
创build用户,则return
相应的错误消息。
现在CreateTodo && DeleteTodo :
他们两个人都用相同的逻辑来处理一些小技巧。
路由代码片段:
app.all('/todos', users.requiresLogin); // Users Routes app.route('/todos') .post(users.hasPerms('globalPerms','privatePerms'), todos.create); .delete(users.hasPerms('globalPerms','privatePerms'), todos.delete);
创build一个Todo, globalPerms
是与上帝 & privatePerms
与超级英雄 ,他们都可以被允许。
这里的窍门将在todos.delete
方法中,只要确保user.id === todos.createById
否则SUPER HERO可能会继续删除由GOD创build的Todos。
ReadTodo :
当一个TODO被创build时,它应该有一个createById
同样被存储,当一个TODO被分配给某个人时,那么createById
和assignedBy
应该被logging下来。
这使得很多其他操作很容易处理。
user.role.globalPerms
– 给GOD所有TODO的数据。
user.role.privatePerms
– 给TODO创build他/她或分配给他/她。
user.role.globalPerms === undefined && user.role.privatePerms === undefined
– 它的MAN,并给TODO的只分配给他。
UpdateTodo&CommentTodo :
这是ReadTODO所做的一切的完全复制品
最后一个, AssignTodo :
简单的一个, loggedInUser.id === todos.createdById
然后他可以把它分配给任何人。
这里要记住两点:
-
由于分配部分主要发生在你的UI(Angular)前面,我已经给出了检查
loggedInUser.id === todos.createdById
。 以任何方式login用户将通过读取操作看到所有TODO,并可将其分配给他/她喜欢的任何人。 -
确保一个超级英雄只能分配一个TODO给自己或其他超级英雄,或一个人,而不是上帝。 你如何显示分配给用户界面的选项不在这个问题的范围之内。 这只是一个头。
希望这是明确的。
注意:没有必要授予在angular色集合MAN的权限,我们pipe理了所有可能的操作。
可能的方法 – >在用户集合/模式中embeddedangular色:用户文档应具有以下内容:
{ _id : "email@mail.com", name: "lorem ipsum", role: "MAN" }
据你的文章描述,只有上帝可以制作和分配TODO。 angular色集合可能包含以下内容:
{ _id : "MAN", globalPerm: [], privatePerm: [], assignedPerm: ["r","u"], }, { _id : "SUPER_HERO", globalPerm: [], privatePerm: ["c","r","u","d"], assignedPerm: ["c","r","u","d"], }, { _id : "GOD", globalPerm: ["c","r","u","d"], privatePerm: ["c","r","u","d"], assignedPerm: ["c","r","u","d"], }
节点JS中间件获取用户的正确权限值后,您可能需要使用中间件。 示例表示HTTP请求路由:
app.post('/updateTodo', permissions.check('privatePerm', 'c'), function (req, res) { // do stuff
};
在实际执行函数体来更新TODO之前调用permissions.check。
因此,如果用户尝试更新待办事项,它将首先validation相应的权限。
这是一个非常广泛的问题,可以通过多种方式解决。
你已经添加了你正在使用MEAN栈,所以我会限制我的问题。
你没有包含在整个问题中的一件事是你使用了什么样的身份validation架构。 假设您正在使用基于令牌的身份validation,通常现在人们使用它。
我们有3种types的用户。 您可以使用不同的选项来区分令牌的types。
- 不同的集合(mongoDB)或Redis设置它们的存储位置
-
encryption的令牌将具有用户的types等等。(如果你不需要在后端存储令牌,你可以解密和检查)
- 这完全取决于用例。
现在,在允许任何用户input用户特定路线之前,请确保您首先检查标记。
例
app.post('/godlevelroute', godtokencheck, callrouteandfunction); app.post('/superherolevelroute', superheroroute, callrouteandfunction);
您必须从angular度发送标头,然后您可以从标题中取出数据,然后您可以检查该特定用户是否有权通过该路线。
比方说,上帝级别的用户login,然后他将有godleveltoken与他,我们会先检查,然后才允许他访问该路线,否则你可以只显示错误信息。
这可以是服务器端的示例标记检查function
function checkToken(req, res, next) { var token = req.headers['accesstoken']; //access token from header //now depending upon which system you are following you can run a check };
节点模块build议: https : //www.npmjs.com/package/jsonwebtoken
现在来到前端部分。 你正在使用基于你写的东西的angular度,你可以在显示任何页面之前拦截令牌。
你可以通过这个博客来获得我试图解释的图片。 点击这里