我正在学习MEAN 堆栈,开发一个简单的TODO应用程序,并希望为此实现基于角色的访问控制(RBAC)。我如何设置角色& MongoDB的许可。
我想要3个角色(角色可能看起来很有趣,但这纯粹是为了学习):
GOD - 与超级管理员类似,可以在应用程序中执行任何操作。 TODO的C,R,U,D权限以及其他用户的权限。可以创建一个TODO&直接分配给任何SUPER HERO或MAN。在任何时间点更新或删除TODO或用户。
SUPER HERO - 与管理员类似,拥有超强的权力可以为他的个人数据做任何事 - C,R,U,D为TODO' s。无法创建任何用户。只能阅读&为GOD& amp;创建的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在哪里应该有PERMISSIONS等。如何将它们全部连接起来?
答案 0 :(得分:16)
我喜欢角色的名字 - GOD,SUPER HERO&男人,易于理解。
当您使用MEAN堆栈并且node
上发生了大量路由验证时,我更希望保持角色表简单。
角色:
{
_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
}
当用户登录并将user
对象发送回客户端时,请确保将roleId
替换为来自DB的相应role
对象。
来自Node JS的代码:
通过完全理解您的用例,我们可以将它们分为以下几种方法 -
CREATEUSER
CreateTodo
DeleteTodo
ReadTodo
CommentTodo
AssignTodo
让我们一步一步走, CreateUser 。
路由代码段:
app.all('/users', users.requiresLogin);
// Users Routes
app.route('/users')
.post(users.hasPerms('globalPerms'), users.create);
在您的控制器中,您可以根据输入globalPerms
进行验证,如果已经过验证,则允许通过调用next()
其他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);
要创建Todo,globalPerms
与 GOD & privatePerms
有 SUPER HERO ,两者都可以被允许。
此处的诀窍将采用todos.delete
方法,只需确保user.id === todos.createById
其他SUPER HERO可以继续删除由GOD创建的Todos。
ReadTodo :
当创建 TODO 时,如果 TODO 分配给某人createById
和{{1},则同样应存储assignedTo
也应该记录下来。
这使得许多其他操作变得容易处理。
assignedBy
- 向上帝提供所有TODO的数据。
user.role.globalPerms
- 将TODO创建给他/她或分配给他/她。
user.role.privatePerms
- 它的MAN并且只给TODO,而这些TODO只被分配给他。
UpdateTodo& CommentTodo :
这是ReadTODO所做的精确复制DIY
最后一个, AssignTodo :
简单的一个,user.role.globalPerms === undefined && user.role.privatePerms === undefined
然后他可以将它分配给任何人。
这里要记住两件事:
由于分配部分主要发生在你的UI(Angular)前面,我已经给出了检查loggedInUser.id === todos.createdById
的方法。以任何方式登录用户都会通过阅读操作查看所有TODO,并可以将其分配给他/她喜欢的任何人。
确保 SUPER HERO 只能将TODO分配给自己或其他SUPER HERO或MAN,但不能分配给GOD。如何在UI前面显示分配给选项超出了此问题的范围。这只是一个提醒。
希望这很清楚。
注意:没有必要在角色集合中为MAN提供权限。我们完成了所有可能的操作。
答案 1 :(得分:1)
这是一个非常广泛的问题,可以通过多种方式解决。
你已经添加了你正在使用MEAN堆栈,因此我将我的问题限制在那里。
您未在整个问题中包含的一件事是您使用的是哪种身份验证体系结构。假设您正在使用基于令牌的身份验证,通常人们现在使用它。
我们有3种类型的用户。 您可以使用不同的选项来区分令牌类型。
加密令牌也会有用户类型等。(如果您不需要在后端存储令牌,这将派上用场,您可以解密并检查)
现在,在允许任何用户进入用户特定路线之前,请确保首先检查令牌。
示例
app.post('/godlevelroute', godtokencheck, callrouteandfunction);
app.post('/superherolevelroute', superheroroute, callrouteandfunction);
您必须从angular发送标头,然后您可以从标头中取出数据,然后您可以检查该特定用户是否有权通过该路由。
让我们说一个神级用户登录然后他会和他一起进行神奇的说法,我们会在允许他访问该路线之前先检查一下,否则你只能显示错误信息。
这可以是服务器端的样本令牌检查功能
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
};
节点模块建议:https://www.npmjs.com/package/jsonwebtoken
现在来到前端部分。您根据所写的内容使用角度,您可以在显示任何页面之前拦截令牌。
您可以浏览此博客,以获得我试图解释的图片。 Click Here
答案 2 :(得分:0)
可能的方法 - >具有嵌入用户集合/架构中的角色: 用户文档应具有以下内容:
{
_id : "email@mail.com",
name: "lorem ipsum",
role: "MAN"
}
就你的帖子所描述的,只有上帝可以制作和分配TODO。 Roles Collection可能包含以下内容:
{
_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。
因此,如果用户尝试更新待办事项,它将首先验证相应的权限。