环回由管理员创建用户但由用户更新配置文件

loopback create user by admin but update profile by user

我尝试使用以下模型在 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));
};

现在我什么都可以了。
只有 admin 可以 创建 新用户并执行任何操作。
$everyone只能登录注销确认帐户.
但是我对 $owner 部分有一些问题。由于管理员创建的用户现在 'admin' 是任何其他用户的所有者,因此没有人不能使用 findByIdupdateAttributes(更新轮廓)。


更新:

我再次测试,新用户可以使用 findById ( GET /Employees/{id} ) (我不知道它为什么起作用,但这就是我们所需要的) BUUUUT 另一个问题,新用户不能使用 updateAttributes ( PATCH /Employees/{id} ) 并显示以下错误:

Authorization Required

为什么 findById ( GET /Employees/{id} ) 有效??
为什么 updateAttributes ( PATCH /Employees/{id} )??
为什么这两个不一样?
你能指导我如何解决这个问题吗?我找不到任何相关信息。

根据您的 ACL,目前只有记录的所有者能够 update/delete 任何数据,为了允许其他用户,您必须将 ACL updateAttributes principalId 更改为 $authenticated。

"acls":
[ 
  { "principalType": "ROLE", "principalId": "$authenticated", "permission": "ALLOW", "property": "updateAttributes" }
],

但这种方法允许任何经过身份验证的用户更改任何其他配置文件,因此为防止此操作,您可以添加 beforeRemote hook 查找当前 userId 和配置文件 userId 以比较它们并允许此值匹配。

But I have some issue with $owner part. Because of user creation done by admin now 'admin' is owner of any other user

如果您使用端点 POST /Employees 创建新用户,则情况并非如此。管理员不是 $owner。见 loopback doc:

To qualify a $owner, the target model needs to have a belongsTo relation to the User model and property matching the foreign key of the target model instance. The check for $owner is only performed for a remote method that has ‘:id’ on the path, for example, 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 时出现了奇怪的行为,并且您使用的自定义混合宏会扰乱 acls 注册。我不明白这个 mixin 应该做什么,但我最好的猜测是问题出在它身上。

从您的项目中删除此文件,重新启动您的服务器并在没有它的情况下进行测试。应该可以解决您的问题。

最后我找到了一个可行的解决方案: 我更改此行:

{ "principalType": "ROLE", "principalId": "$owner", "permission": "ALLOW", "property": "updateAttributes" }

下一行:

{ "principalType": "ROLE", "principalId": "$owner", "permission": "ALLOW", "property": "patchAttributes" }

我在 this file 中找到了它。

这是一个文档问题 here,其中 updateAttributes 更改为 patchAttributes 但在文档中没有更改。