我尝试使用以下模型来管理LoopBack 3 API中的用户管理:
{
"name": "Employee",
"plural": "Employees",
"base": "User",
"idInjection": true,
"options": {
"validateUpsert": true,
"strict": true
},
"mixins": {
"ClearBaseAcls": true
},
"hidden": [
"password",
"verificationToken"
],
"properties": {
"name": {
"type": "string",
"required": true
},
"family": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls":
[ { "principalType": "ROLE", "principalId": "$everyone", "permission": "DENY" },
{ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW", "property": "login" },
{ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW", "property": "logout" },
{ "principalType": "ROLE", "principalId": "$everyone", "permission": "ALLOW", "property": "confirm" },
{ "principalType": "ROLE", "principalId": "admin", "permission": "ALLOW" },
{ "principalType": "ROLE", "principalId": "$owner", "permission": "ALLOW", "property": "findById" },
{ "principalType": "ROLE", "principalId": "$owner", "permission": "ALLOW", "property": "updateAttributes" }
],
"methods": {}
}
并使用此mixis:(ClearBaseAcls)
'use strict';
const path = require('path');
const appRoot = require('app-root-path');
function slugify(name) {
name = name.replace(/^[A-Z]+/, s => s.toLowerCase());
return name.replace(/[A-Z]/g, s => '-' + s.toLowerCase());
}
module.exports = (Model) => {
const configFile = path.join('./common/models/', slugify(Model.modelName) + '.json');
const config = appRoot.require(configFile);
if (!config || !config.acls) {
console.error('ClearBaseAcls: Failed to load model config from', configFile);
return;
}
Model.settings.acls.length = 0;
config.acls.forEach(r => Model.settings.acls.push(r));
};
现在一切都对我好了
只有管理员才能创建新用户并执行任何操作
$ everyone 只能登录,退出和确认帐户。
但是我对 $ owner 部分存在一些问题。由于管理员现在已完成用户创建' admin'是任何其他用户的所有者,任何人都无法使用 findById 或 updateAttributes (更新个人资料)。
更新
我再次测试,新用户可以使用findById(GET / Employees / {id})(我不知道它为什么会起作用,但它只是我们所需要的)BUUUUT另一个问题,新用户无法使用updateAttributes(PATCH / Employees / {id})并显示以下错误:
Authorization Required
为什么 findById (GET / Employees / {id})工作?
为什么 updateAttributes (PATCH / Employees / {id})??
为什么这两个不一样?
你能指导我如何解决这个问题吗?我无能为力。
答案 0 :(得分:1)
根据您的ACL,目前只有记录的所有者才能更新/删除任何数据,以便允许其他用户更改ACL updateAttributes principalId为$ authenticated。
"acls":
[
{ "principalType": "ROLE", "principalId": "$authenticated", "permission": "ALLOW", "property": "updateAttributes" }
],
但是这种方法允许任何经过身份验证的用户更改任何其他配置文件,以防止此操作,您可以为当前userId和配置文件userId添加beforeRemote hook外观以比较它们,并允许此值匹配。
答案 1 :(得分:1)
但我对$ owner部分有一些问题。由于管理员现在已完成用户创建' admin'是任何其他用户的所有者
如果您使用端点POST /Employees
来创建新用户,则不然。管理员不是$所有者。请参阅loopback doc:
要限定$ owner,目标模型需要具有与User模型的belongsTo关系以及与目标模型实例的外键匹配的属性。仅对路径上具有“:id”的远程方法执行$ owner的检查,例如,GET / api / users /:id。
此外,您正在重新定义findById和updateAttributes acls,但they are already defined in loopback是基本用户的一部分。所以你可以删除那两行。
{ "principalType": "ROLE", "principalId": "$owner", "permission": "ALLOW", "property": "findById" },
{ "principalType": "ROLE", "principalId": "$owner", "permission": "ALLOW", "property": "updateAttributes" }
现在,您在使用ACLS时遇到了奇怪的行为,并且您使用的是自定义mixin,它与acls注册混淆。我不确切地理解这个混合应该做什么,但我最好的猜测是问题来自它。
从项目中删除此文件,重新启动服务器并在没有它的情况下进行测试。应该解决你的问题。
答案 2 :(得分:0)
最后我找到了一个有效的解决方案: 我改变了这一行:
{ "principalType": "ROLE", "principalId": "$owner", "permission": "ALLOW", "property": "updateAttributes" }
到下面一行:
{ "principalType": "ROLE", "principalId": "$owner", "permission": "ALLOW", "property": "patchAttributes" }
我在this file找到了它。
这是一个文档问题here,其中updateAttributes
已更改为patchAttributes
,但在文档中未更改。