3

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

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

这是我到目前为止一直在尝试的:

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

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

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

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

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

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

4

2 回答 2

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

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

于 2016-06-14T22:10:26.043 回答
0

嘿,要完成您想做的事情,您必须在文件的元数据中添加允许读取文件的用户的 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;
}

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

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

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

于 2017-09-27T01:39:03.400 回答