带环回的粒度访问控制
Granular access control with loopback
我正在使用最新版本的环回,现在我想处理 acl。我的应用程序有一个项目模型,应该可供团队成员、相关所有者和管理员使用。当然,我希望有多个项目,其成员可以是多个项目的团队成员……所有者可以拥有多个项目,管理员应该能够看到所有内容并执行所有操作。
Loopback 似乎可以定义它。
你会如何处理?
谢谢
首先,在启动脚本中定义静态角色
eq:TeamMeamber、所有者、管理员等
看这个例子https://loopback.io/doc/en/lb3/Defining-and-using-roles.html#static-roles
//create the admin role
Role.create({
name: 'admin'
}, function(err, role) {
});
然后在您的引导脚本中为您的角色注册 RoleResolver。这是判断是否请求角色适用或不适用的逻辑。
来自上面的例子link。
Role.registerResolver('teamMember', function(role, context, cb) {
// Q: Is the current request accessing a Project?
if (context.modelName !== 'project') {
// A: No. This role is only for projects: callback with FALSE
return process.nextTick(() => cb(null, false));
}
//Q: Is the user logged in? (there will be an accessToken with an ID if so)
var userId = context.accessToken.userId;
if (!userId) {
//A: No, user is NOT logged in: callback with FALSE
return process.nextTick(() => cb(null, false));
}
// Q: Is the current logged-in user associated with this Project?
// Step 1: lookup the requested project
context.model.findById(context.modelId, function(err, project) {
// A: The datastore produced an error! Pass error to callback
if(err) return cb(err);
// A: There's no project by this ID! Pass error to callback
if(!project) return cb(new Error("Project not found"));
// Step 2: check if User is part of the Team associated with this Project
// (using count() because we only want to know if such a record exists)
var Team = app.models.Team;
Team.count({
ownerId: project.ownerId,
memberId: userId
}, function(err, count) {
// A: The datastore produced an error! Pass error to callback
if (err) return cb(err);
if(count > 0){
// A: YES. At least one Team associated with this User AND Project
// callback with TRUE, user is role:`teamMember`
return cb(null, true);
}
else{
// A: NO, User is not in this Project's Team
// callback with FALSE, user is NOT role:`teamMember`
return cb(null, false);
}
});
});
});
然后在您的模型中,按名称使用这些角色,
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "admin",
"permission": "ALLOW",
"property": "findById"
}
所以基本上,
- 你创建了几个角色
- 然后在你的模型定义中声明什么角色
有权访问 READ、WRITE 或 EXECUTE 自定义(列表)
方法
- 然后使用角色解析器,它将 运行 用于那些具有这些角色的模型,并决定角色是否适用于请求的当前上下文。
我正在使用最新版本的环回,现在我想处理 acl。我的应用程序有一个项目模型,应该可供团队成员、相关所有者和管理员使用。当然,我希望有多个项目,其成员可以是多个项目的团队成员……所有者可以拥有多个项目,管理员应该能够看到所有内容并执行所有操作。
Loopback 似乎可以定义它。
你会如何处理?
谢谢
首先,在启动脚本中定义静态角色 eq:TeamMeamber、所有者、管理员等
看这个例子https://loopback.io/doc/en/lb3/Defining-and-using-roles.html#static-roles
//create the admin role
Role.create({
name: 'admin'
}, function(err, role) {
});
然后在您的引导脚本中为您的角色注册 RoleResolver。这是判断是否请求角色适用或不适用的逻辑。
来自上面的例子link。
Role.registerResolver('teamMember', function(role, context, cb) {
// Q: Is the current request accessing a Project?
if (context.modelName !== 'project') {
// A: No. This role is only for projects: callback with FALSE
return process.nextTick(() => cb(null, false));
}
//Q: Is the user logged in? (there will be an accessToken with an ID if so)
var userId = context.accessToken.userId;
if (!userId) {
//A: No, user is NOT logged in: callback with FALSE
return process.nextTick(() => cb(null, false));
}
// Q: Is the current logged-in user associated with this Project?
// Step 1: lookup the requested project
context.model.findById(context.modelId, function(err, project) {
// A: The datastore produced an error! Pass error to callback
if(err) return cb(err);
// A: There's no project by this ID! Pass error to callback
if(!project) return cb(new Error("Project not found"));
// Step 2: check if User is part of the Team associated with this Project
// (using count() because we only want to know if such a record exists)
var Team = app.models.Team;
Team.count({
ownerId: project.ownerId,
memberId: userId
}, function(err, count) {
// A: The datastore produced an error! Pass error to callback
if (err) return cb(err);
if(count > 0){
// A: YES. At least one Team associated with this User AND Project
// callback with TRUE, user is role:`teamMember`
return cb(null, true);
}
else{
// A: NO, User is not in this Project's Team
// callback with FALSE, user is NOT role:`teamMember`
return cb(null, false);
}
});
});
});
然后在您的模型中,按名称使用这些角色,
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "admin",
"permission": "ALLOW",
"property": "findById"
}
所以基本上,
- 你创建了几个角色
- 然后在你的模型定义中声明什么角色 有权访问 READ、WRITE 或 EXECUTE 自定义(列表) 方法
- 然后使用角色解析器,它将 运行 用于那些具有这些角色的模型,并决定角色是否适用于请求的当前上下文。