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 中,权限是这样强制执行的:
- 总是允许超级用户。
- 明确拒绝的用户和角色始终被拒绝。
- 如果记录没有允许规则,则访问权限为 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 以获得实际的方法文档。
这些单独的规则一开始可能很棘手,但它们确实很强大。让我们做一些例子。我如何使用这些规则来...
- 拒绝所有人访问:--> 为管理员设置唯一允许规则
- 允许登录用户访问但不允许某些人 Peter(例如当您阻止某人是聊天应用程序时):--> 为
loggedin
角色和 Peter 的拒绝规则。
- 只允许从后端代码模块访问: --> 为
node
角色设置允许规则(角色解释见下文)。
我可以授予或拒绝谁访问权限?
您可以在允许和拒绝规则中使用两个实体:
- 可以授予或拒绝来自预定义用户 table 的用户访问权限
- 可以授予或拒绝在预定义角色 table 中定义的用户组访问权限
- 预定义角色
admin
、loggedin
(代表所有登录用户)和node
(代表访问数据库的后端代码模块)
我的 table 的默认访问权限是什么?
表和对象 public默认情况下可以访问,如果没有另外配置的话。
关于属性级 ACL
Baqend 中没有属性级 ACL。这意味着当您有一个带有私有电子邮件地址和 public 名称的用户对象时,您只能将该对象设为私有或 public.
这个问题的解决方案是使用两个对象,一个用于私人信息,一个用于 public 信息,然后 link 这两个。对于用户,这意味着您将实际的用户对象设为私有并定义一个新的配置文件 table,您可以在其中保存 public 用户信息。
虽然此解决方案在定义您的架构时需要更多工作,但有 很好的理由 为什么 Baqend 不支持属性级 ACL。无需过多赘述:
- 更好的缓存。属性级 ACL 会严重限制我们缓存的方式,从而加速您的数据库请求。
- 昂贵的评价。属性级 ACL 更难评估,因此会减慢数据库访问速度。另一方面,对象级 ACL 可以下推到我们的数据库系统,并且可以非常有效地进行评估。
少了点东西
希望这些解释有助于更好地理解ACL系统。如果这里有什么遗漏,请评论,我会补充。
我正在尝试弄清楚这是否可以通过 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 中,权限是这样强制执行的:
- 总是允许超级用户。
- 明确拒绝的用户和角色始终被拒绝。
- 如果记录没有允许规则,则访问权限为 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 以获得实际的方法文档。
这些单独的规则一开始可能很棘手,但它们确实很强大。让我们做一些例子。我如何使用这些规则来...
- 拒绝所有人访问:--> 为管理员设置唯一允许规则
- 允许登录用户访问但不允许某些人 Peter(例如当您阻止某人是聊天应用程序时):--> 为
loggedin
角色和 Peter 的拒绝规则。 - 只允许从后端代码模块访问: --> 为
node
角色设置允许规则(角色解释见下文)。
我可以授予或拒绝谁访问权限?
您可以在允许和拒绝规则中使用两个实体:
- 可以授予或拒绝来自预定义用户 table 的用户访问权限
- 可以授予或拒绝在预定义角色 table 中定义的用户组访问权限
- 预定义角色
admin
、loggedin
(代表所有登录用户)和node
(代表访问数据库的后端代码模块)
我的 table 的默认访问权限是什么?
表和对象 public默认情况下可以访问,如果没有另外配置的话。
关于属性级 ACL
Baqend 中没有属性级 ACL。这意味着当您有一个带有私有电子邮件地址和 public 名称的用户对象时,您只能将该对象设为私有或 public.
这个问题的解决方案是使用两个对象,一个用于私人信息,一个用于 public 信息,然后 link 这两个。对于用户,这意味着您将实际的用户对象设为私有并定义一个新的配置文件 table,您可以在其中保存 public 用户信息。
虽然此解决方案在定义您的架构时需要更多工作,但有 很好的理由 为什么 Baqend 不支持属性级 ACL。无需过多赘述:
- 更好的缓存。属性级 ACL 会严重限制我们缓存的方式,从而加速您的数据库请求。
- 昂贵的评价。属性级 ACL 更难评估,因此会减慢数据库访问速度。另一方面,对象级 ACL 可以下推到我们的数据库系统,并且可以非常有效地进行评估。
少了点东西
希望这些解释有助于更好地理解ACL系统。如果这里有什么遗漏,请评论,我会补充。