Baqend 中的关系和 ACL

Relationships and ACL in Baqend

我正在尝试弄清楚这是否可以通过 baqend 实现,甚至是正确的开始方法。

我有一帮用户,使用的是Baqend自带的默认用户账户系统。

其中一些用户将成为公司的管理员。一家公司会有 1 到 5 名管理员用户。

有一个单独的数据 class,其中包含一条公司记录和一组作为管理员的用户。

像这样:

{
  id: "/db/Companies/123-456-789",
  name: "Test Co",
  admins: [
    { id: "/db/Users/10", name: "Joe Schmo" },
    { id: "/db/Users/11", name: "Kate Skate" },
    { id: "/db/Users/12", name: "Johny Begood" }
  ]
}

确保只有用户 10、11 和 12 可以修改 admins 数组的内容以及 /db/Companies/123-456-789 中包含的任何其他内容的方法是什么?

是否像将其他管理员的信息插入数组并同时或之后将该人添加到 /db/Companies/123-456-789 的 ACL 一样简单?

还有删除个人ACL的方法是什么?我在这里看到如何设置它:https://www.baqend.com/guide/topics/user-management/#permissions 但我们如何删除或删除?显式拒绝 ACL 中的该用户与根本不存在的用户之间有什么区别(我想默认情况下被拒绝?假设整个集合首先设置为 NOT public)。

对于我们的使用,仅仅因为管理员离开并不意味着他离开了我们的应用程序,他可能会为另一个使用我们应用程序的客户工作,并且他的用户帐户应该仍然有效,但不能再访问公司记录.

我认为您已经说得很对了:您可以通过将管理员添加到 admins 数组并在 ACL 中明确允许他们进行读写访问来将管理员添加到公司。要删除管理员权限,您只需删除即将成为前管理员的显式 allow 规则。

在 Baqend 中,权限是这样强制执行的:

  1. 总是允许超级用户。
  2. 明确拒绝的用户和角色始终被拒绝。
  3. 如果记录没有允许规则,则访问权限为 public。只要存在至少一个允许规则,就只允许允许的用户访问。

由于每条记录都是 public,除非至少有一个 allow 规则,当您允许管理员访问时,您的记录将受到保护。但是,一旦您从访问规则集中删除最后一位管理员,它将再次变为 public。因此,始终明确允许对您的 Baqend 应用程序管理员进行写访问可能是个好主意,这样总是至少有一个 allow 规则。

让我试着解释一下 Baqend 中的 ACL 是如何工作的。

TL;DR

为了保护您的对象 /db/Companies/123-456-789 您可以简单地为您的三个用户 ID(/db/Users/10/db/Users/11/db/Users/12)中的每一个添加一个允许规则到对象您公司对象的 ACLS 是这样的:

db.Companies.load("/db/Companies/123-456-789").then(function(company) {
  company.allowWriteAccess("/db/Users/10");
  company.allowWriteAccess("/db/Users/11");
  company.allowWriteAccess("/db/Users/12");

  return company.save();
})

这确保只有这些用户可以编辑公司对象。值得注意的是,此规则列表独立于公司对象中包含的管理员列表。要撤销用户的写入权限,您可以像我们之前使用 allowWriteAccess 一样使用 deleteWriteAccess。 这意味着您的用户无需离开您的应用即可轻松离开公司。

我希望这能回答您的问题。因为 ACL 很复杂,所以我现在将尝试更详细地解释一般方法。

ACL 的工作原理

在哪个级别可以控制访问?

有两个级别可以控制对您的数据的访问:

  • 在 table 级别(所谓的模式 ACL)
  • 在对象级别(所谓的对象 ACL)

Schema ACL 定义谁可以访问 table in general.例如,您可以通过仅向管理员授予读取权限来定义用户 table 对 public 不可读:

allowReadAccess("/db/Role/admin")  // Schema ACLs can only be set by the admin

您可以为读取更新插入和[=81=定义规则]分别在table上查询。

对象 ACL 定义了较低级别的访问权限。您可以使用它来拒绝对特定对象的访问。例如,您可以定义只有用户自己可以更新自己的 User 对象,如下所示:

allowWriteAccess("<userId>")

对于对象,可以分别定义的规则。

现在谁有访问权限(如何评估权限)?

为了访问对象,用户需要具有访问 table(架构 ACL)的一般权限以及访问对象本身(对象 ACL)的权限。这意味着如果架构 ACL 授予您访问权限,则首先评估它们,同时评估对象 ACL。

我可以定义哪些规则?

可以定义两种类型的规则来允许或拒绝访问:

  • 允许规则 定义一般谁有访问权限。首先检查这些规则。如果您不定义允许规则,则每个人都具有一般访问权限。
  • 拒绝规则 定义谁被拒绝访问(即使用户被 允许规则 允许)。这些规则在允许规则之后检查。

查看 JS API for ACLs 以获得实际的方法文档。

这些单独的规则一开始可能很棘手,但它们确实很强大。让我们做一些例子。我如何使用这些规则来...

  1. 拒绝所有人访问:--> 为管理员设置唯一允许规则
  2. 允许登录用户访问但不允许某些人 Peter(例如当您阻止某人是聊天应用程序时):--> 为 loggedin 角色和 Peter 的拒绝规则。
  3. 只允许从后端代码模块访问: --> 为node角色设置允许规则(角色解释见下文)。

我可以授予或拒绝谁访问权限?

您可以在允许和拒绝规则中使用两个实体:

  • 可以授予或拒绝来自预定义用户 table 的用户访问权限
  • 可以授予或拒绝在预定义角色 table 中定义的用户组访问权限
  • 预定义角色adminloggedin(代表所有登录用户)和node(代表访问数据库的后端代码模块)

我的 table 的默认访问权限是什么?

表和对象 public默认情况下可以访问,如果没有另外配置的话。

关于属性级 ACL

Baqend 中没有属性级 ACL。这意味着当您有一个带有私有电子邮件地址和 public 名称的用户对象时,您只能将该对象设为私有或 public.

这个问题的解决方案是使用两个对象,一个用于私人信息,一个用于 public 信息,然后 link 这两个。对于用户,这意味着您将实际的用户对象设为私有并定义一个新的配置文件 table,您可以在其中保存 public 用户信息。

虽然此解决方案在定义您的架构时需要更多工作,但有 很好的理由 为什么 Baqend 不支持属性级 ACL。无需过多赘述:

  1. 更好的缓存。属性级 ACL 会严重限制我们缓存的方式,从而加速您的数据库请求。
  2. 昂贵的评价。属性级 ACL 更难评估,因此会减慢数据库访问速度。另一方面,对象级 ACL 可以下推到我们的数据库系统,并且可以非常有效地进行评估。

少了点东西

希望这些解释有助于更好地理解ACL系统。如果这里有什么遗漏,请评论,我会补充。