loopback按管理员创建用户,但用户

时间:2017-04-29 11:45:44

标签: javascript node.js acl loopbackjs loopback

我尝试使用以下模型来管理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})??
为什么这两个不一样?
你能指导我如何解决这个问题吗?我无能为力。

3 个答案:

答案 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,但在文档中未更改。