我需要一些专家意见来实现Express js中的角色和权限。我计划使用Express js开发Restful Api,但是没有足够的信息来实现角色和权限,尽管有很多选项可用于身份验证和授权。
答案 0 :(得分:17)
创建表格
首先,您需要创建将保存角色,权限和资源之间关联的表:
您可能不需要权限表的那种粒度,但有些人喜欢它。例如,您不需要'拒绝',因为您只需检查Read!= true。
现在,当您需要角色对资源的权限时,您只需查找role_id和resource_id,并检查哪些权限设置为true。
创建中间件
由于您使用快速,因此中间件很容易添加。例如,假设您有一个名为users的路由器:
public class MyClass : IValidatableObject
{
[Required(ErrorMessage="Please enter a Start Date")]
public DateTime? StartDate { get; set; }
[Required(ErrorMessage="Please enter an End Date")]
public DateTime? EndDate { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext context)
{
if (EndDate < StartDate)
{
yield return new ValidationResult("Invalid date range: End date must be greater then the Start Date");
}
}
}
假设您在请求上有某种标记,用于标识发布帖子的用户,并将用户实例附加到请求对象,您可以这样做:
users.post('/', getAuth, handleUserPost)
这个代码只是为了这个例子而被粗暴对待,所以我不会复制并粘贴它,但它应该给你正确的想法。
答案 1 :(得分:3)
Node.js中的角色
第1部分:什么是角色和权利?
角色权限的实现是任何软件的重要组成部分。角色是责任的一种,每个责任都享有赋予他们的某些权利。少数角色之间可能有一些共同的权利,而某些权利可能严格属于特定角色。
权利是授予角色访问权限的Urls。因此有必要在db中创建集合,以存储角色的权利信息。 我们的角色收集模式为
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const RoleSchema = new Schema({
roleId:{
type:String,
unique:true,
required:[true,"Role Id required"]
},
type:{
type:String,
unique:true,
required:[true,"Role type is required"]
},
rights:[{
name: String,
path: String,
url: String
}]
});
module.exports = Role = mongoose.model('role',RoleSchema);
现在请记住,假定存在的每个角色都在Role集合中,并且具有上述架构类型。
在对象的模式权限数组中,我们看到该对象具有键:
因此,如果具有角色 user 的用户有权更改用户名,那么他可以访问url
/users/set-username
。但是,流浪者将无法访问此url。从逻辑上来说,像admin和superadmin之类的较高角色应该有权访问所有较低角色的权限(URL)。
在实际应用中的作用是:-
直到现在我们已经了解了什么是正确的,以及如何将其映射到角色。
第1.5部分:已注册的网址/配置网址
在这里,我们有一个名为registeredUrls.js的文件,如下所示:
module.exports = {
simple:{
"/":[""],
'/users/':["login","register"],
},
auth:{
//admin
'/admin/': ['load-users' , 'set-new-password','delete-user'],
'/teacher/':["add-teacher","delete-teacher","edit-teacher"],
'/student/':["add-student","delete-student","edit-student","test-result"],
//user
'/test/':["view-test","submit-test"],
'/profile/': ['change-username', 'update-profile-data', 'set-new-password', 'upload-pic', 'update-social-links'],
'/teacher/':['load-teacher'],
'/student/':['load-student']
}
}
类似confgUrls.js
const configUrls= {
'/roles/': ['get-rights', 'create', 'update-rights', 'load', 'delete', 'assign']
}
module.exports = configUrls;
第2部分:创建SuperAdmin
这是应用程序中最重要的部分。每当服务器首次启动或重新启动/重新引导时,都会发生此步骤。在config / init.js中,请遵循以下步骤:
在此函数调用结束时,我们始终确保在应用程序中拥有一个已初始化其所有复杂URL /权限的超级管理员。
第3部分:特定于Super-Admin的网址
这些是仅超级管理员享有的权利,必须与注册的url文件并行保存在单独的文件中,其中包括映射仅由superadmin使用的路由的url权利。 在这里,我们有创建角色,加载角色,roleId的获取权限,roleId /角色类型的更新权限,为用户分配角色,删除角色的路由。
对于代码中的每个用户,我们需要将其角色从来宾更改为用户(例如在验证电子邮件后),或者将超级用户使用分配角色url将来宾/用户更改为管理员,然后使用路由更新权限来更新管理员权限。
该过程确保每个角色都具有收款凭证并在其中具有填充权限。
第4部分:Authenticator中间件
这是我们的 RBACS 逻辑的核心。在这里,我们使用遵循以下过程的中间件:
1。
用auth-urls(registeredUrls.js)和super-admin-specific-urls(confgUrls.js)填充简单身份验证URL,并在不同的[SIMPLE_URLS]中填充简单身份验证URL。2。然后检查是否(AUTH_URLS.indexOf(request.url)> -1){-1第三步},否则(SIMPLE_URLS.indexOf(request.url)>-1){那么这是公共网址,那么简单地允许next()}否则{响应未知网址}
3。在这一步中,我们知道在AUTH_URLS中请求的url要求对授权令牌头进行令牌检查(如果找到),然后从令牌中提取令牌。{第四步}。如果未找到授权头,则响应“必需令牌” /“未知”。
4。找到令牌,现在验证此令牌是否具有有效的会话。如果是,请{5th step}否则找不到令牌会话再次登录。 5。验证jwt令牌进行验证{6.step},否则返回“无效的jwt令牌”。
6。直到现在正确请求的url和令牌会话存在且jwt有效令牌。现在使用会话中的角色类型信息(存储在会话中是用户和令牌的基本信息)在此用户会话角色的角色中找到-type,因此我们拥有它的权限[]。现在,看看request.url是否包含在权限[]中。如果找到了{第七步}否则{响应“未找到角色/未知用户”}。
7。如果找到,则{可以访问此URL next()}否则{响应“访问被拒绝”}