【问题标题】:Firebase - Limit file access to specific usersFirebase - 限制特定用户的文件访问权限
【发布时间】:2016-10-15 16:26:50
【问题描述】:

我正在尝试使用 Firebase 实现以下行为:

  • 用户使用 Firebase 身份验证登录
  • 用户将文件上传到 Firebase 存储
  • 用户输入其他用户的电子邮件地址。此用户帐户可能已经存在。如果没有,收件人会收到一封电子邮件,提示他们注册。
  • 上传的文件现在应该仅供上传文件的用户(读/写)和使用上述电子邮件地址的其他用户使用(只读)。

这是我迄今为止一直在尝试的:

  • 使用 FirebaseAuth 注册后,我将用户的电子邮件地址和 uid 存储在实时数据库中。
  • 在用户上传文件并输入收件人的电子邮件地址后,我会在实时数据库中检查该地址。如果存在,我会检索收件人的 uid 并将其存储在文件的元数据中。
  • 在我的 Firebase 存储安全规则中,我检查 auth.uid 是否与存储在文件元数据中的 uid 匹配。

这应该很好用,但是如果用户帐户还不存在怎么办?

  • 我可以在用户输入收件人的电子邮件地址后创建一个新帐户。如果我这样做,我必须指定一个密码。我可以指定一个随机密码并使用密码重置电子邮件,但这不是一个好的用户体验,还因为您无法完全自定义重置电子邮件。

  • 如果我不立即创建新帐户,如何确保只有拥有此电子邮件地址的用户才能访问该文件?将电子邮件地址存储在文件的元数据中不起作用,因为它以后可能会更改。

我觉得我在这里想得太复杂了。有没有更简单的方法来实现这一点,还是我忽略了什么?

编辑:我进行了更多调查,我认为一种方法是使用自定义身份验证令牌,这是 Firebase 存储指南 here 所建议的。不过,这需要我设置自己的身份验证服务器,这首先违背了使用 Firebase 身份验证的目的。有没有更简单的方法来实现这一点?

【问题讨论】:

  • 你将这些文件上传到什么地方?
  • @FrankvanPuffelen Firebase Storage,我已经更新了问题以澄清。

标签: firebase firebase-realtime-database firebase-authentication firebase-storage


【解决方案1】:

嘿,要完成你想做的事情,你必须在文件的元数据中添加允许读取文件的用户的 uid,然后检查令牌的 uid 是否包含在元数据中。

类似这样的:

match /internal/{imageId} {
  allow read: if resource.metadata[request.auth.uid] != null;
}

resource.metadata 是一个映射,因此为了让事情井井有条,您可以在 canRead 参数下拥有所有具有读取权限的 uid,因此它看起来像这样:

match /internal/{imageId} {
   allow read: if resource.metadata.canRead[request.auth.uid] != null;
}

在“使用文件元数据”https://firebase.google.com/docs/storage/987654321@ 下管理通过 firebase 文档读取的元数据

在此处阅读有关安全性的更多信息: https://firebase.google.com/docs/storage/security/user-security, https://firebase.google.com/docs/reference/security/storage

另外,我不确定使用 uid 填充元数据是否是一种好习惯。我不确定您在那里保存的数据量是否有限制。希望这会有所帮助!

【讨论】:

    【解决方案2】:

    这应该相当简单:

    files
      file_id_0
        file_name: My File
        read_write: uid_0
        read_only:
          uid_1: true
          uid_2: true
    

    当然你也有用户

    users
      uid_0
        name: Larry
        email: larry@stooges.com
      uid_1
        name: Curly
        email: curly@stooges.com
      uid_2
        name: Moe
        email: moe@stooges.com
    

    还有一些漂亮的概念性规则

    rules
      .read: false
      .writ: false
      files
        $file_id
          //give the person that uploaded the file read access to this node as well as
          //  any user id that exists in the read_only node
          .read: root.child('files').child($file_id).child('read_write').val = auth.uid ||
                root.child('files').child($file_id).child("read_only').child(auth.uid) = true
         //write access only to the user that created it
         .write: root.child('files').child($file_id).child('read_write').val = auth.uid
    

    这很接近。

    所以当 uid_0 上传一个文件 My File 时,它​​存储在 file_id_0 中。然后,该用户通过他们的电子邮件(假设他们存在)“邀请”另一个用户到该文件。在这种情况下 uid_0 邀请 uid_1 和 uid_2 并且这些用户 id 被写入 file_id_0 节点。这些将通过在 /users 节点中查询这两个用户来获得。

    关键是邀请另一个尚不存在的用户。

    我认为他们在那里玩是有一个电子邮件监视列表节点。

    watch_list
       uid_0
         moe@stooges.com:  file_id_0
    

    每个用户观察用户节点,如果新添加的用户电子邮件存在于他们的观察列表中(uid_0 正在观察 moe@stooges.com)。然后将它们添加到 file_id_0 /read_only 节点并将其从监视列表中删除。

    看我刚才写的,有点不雅所以应该有更好的办法。

    【讨论】:

    • 您上面添加的规则仅适用于实时数据库,对吗? Firebase 存储的规则是什么? Firebase 存储规则能否以某种方式与实时数据库集成?
    • @avf 好吧,不。 Firebase 为存储设计了一套完全不同的规则和完全不同的规则语言。不知道当时的想法是什么。所以我的回答部分适用,因为它控制事物的数据库端,而不是存储。您将需要两者,因此希望 Firebaser 能够介入并提供存储规则解决方案。
    猜你喜欢
    • 2023-03-29
    • 1970-01-01
    • 2010-11-01
    • 2021-06-18
    • 2018-05-07
    • 2017-01-25
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多