首页 文章

Firebase - 限制对特定用户的文件访问

提问于
浏览
4

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

  • 用户使用Firebase身份验证登录

  • 用户将文件上传到Firebase存储

  • 用户输入其他用户的电子邮件地址 . 此用户帐户可能已存在 . 如果没有,收件人会收到一封电子邮件,提示他们注册 .

  • 上传的文件现在应该只对上传它(读/写)的用户和上面的电子邮件地址(只读)的其他用户可用 .

这是我到目前为止所尝试的:

  • 使用FirebaseAuth进行注册后,我将用户的电子邮件地址和 uid 存储在实时数据库中 .

  • 用户上传文件并输入收件人后's email address, I check the Real-Time Database for that address. If it exists, I retrieve the recipient' s uid 并将其存储在文件的元数据中 .

  • 在我的Firebase存储安全规则中,我检查 auth.uid 是否与文件元数据中存储的 uid 匹配 .

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

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

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

我有一种感觉,我觉得这里太复杂了 . 有没有更简单的方法来实现这一目标,还是我忽略了什么?

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

2 回答

  • 1

    这应该是相当简单的:

    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节点并将其从监视列表中删除 .

    看看我刚写的内容,它有点不雅,所以可能有更好的方法 .

  • 0

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

    像这样的东西:

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

    resource.metadata是一个 Map ,所以为了保持组织有序,你可以让所有的uid都有权在canRead参数下读取,所以它看起来像这样:

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

    通过"Use File Metadata" https://firebase.google.com/docs/storage/管理firebase文档中读取的元数据

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

    此外,我不确定是否使用uids填充元数据是一种很好的做法 . 我不确定你在那里保存的数据是否有限制 . 希望这可以帮助!

相关问题