像 faunadb 这样的无服务器数据库是否支持基于角色的身份验证?

does serverless databases like faunadb support role based auth?

总的来说,我是无服务器架构的新手,我正在研究将我当前的 php/mysql rest api 迁移到无服务器架构。

我主要关心的是访问控制。

在某些应用程序中,我允许用户根据角色和分配给他们的组访问内容“

示例

角色:用户:[1,2,3]只能访问group_id的内容:1 | | 2 || 3

是否可以在像 faunadb 这样的无服务器数据库中进行这样的访问控制?

可以使用 FaunaDB 进行此类访问控制,使用 ABAC 系统可以进行更多操作 (https://docs.fauna.com/fauna/current/security/abac.html)

角色:

本质上,您拥有 角色,这些角色提供权限

CreateRole({
  name: "access_todos",
  privileges: [{
    resource: Collection("todos"),
    actions: {
      create: true,
      update: true,
      delete: true,
      write: true
    }
  }]
})

(您可能会注意到,这当然可以访问所有组,这不是您想要的,我们会解决的)

角色可以分配给不同的事物:

  • Keys: 只需用该角色创建一个密钥,该密钥只​​能访问组集合
  • 函数:用户定义函数(如存储过程)可以承担一个角色。
  • 集合中的实体或集合的一部分:任何实体(例如用户、ShareLinks、帐户)都可以通过添加“成员资格”来分配角色。

角色成员资格(将角色分配给数据库实体):

您使用成员字段为数据库实体分配角色。 在这种情况下,您数据库中的所有帐户都将拥有这些权限。您还可以使用这里的功能来过滤掉某种类型的帐户等。

CreateRole({
  name: "access_todos",
  membership: [{ resource: Collection("accounts") }],
  privileges: [{
    resource: Collection("todos"),
    actions: {
      create: true,
      update: true,
      delete: true,
      write: true
    }
  }]
})

假定该实体的身份,(获取该数据库实体的密钥):

那么问题来了:"how do we assume the identity of a user?"。 我们为此使用登录。首先,您使用密码创建一个帐户:

Create(
    Class("account"),
    {
      data: { email: "alice@example.com" }
      credentials: { password: "secret password" },
    }));

重要的部分是credentials.password字段,它是FaunaDB的特殊字段。它将被加密,当数据库实体有这样的密码时,您可以使用 Login 来假设实体的身份:

Login(
    Index("accounts_by_email"), "alice@example.com"),
    { password: "secret password" })

登录将为您提供一个令牌,该令牌现在将拥有该帐户所拥有的所有权利。或者换句话说,集合 'accounts' 的这个数据库实体是其成员的角色的所有特权(并且成员资格是在具有成员资格键的角色上定义的)

角色谓词和 'Identity()' 功能的强大功能

好的,但是我们如何获得更细粒度的访问权限? 角色可以有 lambda 谓词而不是布尔值。这意味着在您的情况下,您可以将组数组存储在用户身上(反之亦然),并将帐户 link 存储在用户身上。

privileges: [
  {
    resource: Collection("Groups"),
    actions: {
      read: Query(
        Lambda("groupReference",
          // Write your logic
        )
      )
    }
  }
]

在这样的查询中,lambda 参数是您尝试访问的实体(例如组)的引用 一个问题仍然存在……我们如何检查 link 登录帐户的用户是否有权访问这些组?好吧,我们使用 'Identity()' 作为 FQL 函数,returns 引用当前登录的数据库实体。

注意:默认情况下,您可以 read/write 访问您登录的实体。因此,您不想将组 ID 存储在帐户中,因为理论上用户可以更改这些 ID。这就是我在解释中拆分帐户和用户的原因。我们可能会在未来的 FQL 版本中更改它,因为这似乎是 confusing/cumbersome.

一些不错的资源: - ABAC 文档:https://docs.fauna.com/fauna/current/security/abac.html - 带有 GraphQL 的 ABAC:https://medium.com/fauna/abac-graphql-6e3273945b1c - 身份验证文档:https://app.fauna.com/tutorials/authentication#creating-users

我们正在构建一个完整的例子,我希望在未来几周内出现在我们的博客上。