基于 Firestore 数据的 Firebase 云存储规则解决方法

标签 firebase google-cloud-platform google-cloud-firestore google-cloud-storage firebase-security

在我的 firebase 应用程序中,我有

  • 用户列表(所有用户均通过 Firebase 身份验证注册)
  • 每个用户的关注者列表
  • 每个用户都添加了一张个人资料照片,照片的文件名是唯一的,并保存在名为“photoName”文档的 firestore 文档中
  • 只有用户的关注者才有权阅读“photoName”文档(如 firestore 规则中指定)

我希望只有关注者才能读取用户的个人资料照片,我在云存储中添加了一条规则,如下所示:

match /profilePhotos/{profilePhotoFile_id} {

  allow read: if request.auth.uid != null

}

云存储规则是在文件级别设置的,因此我假设只有登录并且也是关注者的用户才能读取其他用户的个人资料照片,这是否准确?除非他们以某种方式神奇地猜出照片的唯一名称。

最佳答案

更新日期为 2022 年 9 月 28 日

Cloud Storage for Firebase 中的安全规则现在支持跨服务规则,让您可以查询项目的 Firestore 数据,类似于 get()exists() Firestore 规则中的函数。

查看此Firebase blog article还有这个SO answer from Puf .

上一个答案

Is it accurate for me to assume that only the users who are logged in and are also a follower will be able to read the profile photo of another user?

否,因为客户端 SDK 可以列出 Cloud Storage 存储桶中的所有文件,如 explained in the doc并且您的云存储安全规则允许任何经过身份验证的用户读取个人资料照片文件。

另请注意,编写云存储安全规则时无法读取 Firestore 文档。


一种可能的方法是使用 Cloud Function生成存储在 Firestore 文档中的签名 URL,并且禁止对个人资料照片文件进行读取访问。由于 Cloud Functions 使用 Admin SDK,因此它们可以绕过安全规则。

每次将文件添加到 Cloud Storage 时,以下 Cloud Function 代码都会生成一个签名 URL,并将其保存在 Firestore 文档中。通过此签名 URL,任何人都可以读取个人资料照片文件。

您可以根据自己的情况进行调整:

  1. 如有必要,仅处理个人资料照片(检查文件名是否包含 profilePhotos)
  2. 将 URL 保存在正确的 Firestore 文档中:我猜该文件名允许链接回用户文档。另外,您可能需要从 add() 更改为 update()

exports.generateFileURL = functions.storage.object().onFinalize(async object => {

    try {
        const bucket = admin.storage().bucket(object.bucket);
        const file = bucket.file(object.name);

        const signedURLconfig = { action: 'read', expires: '08-12-2025' };

        const signedURLArray = await file.getSignedUrl(signedURLconfig);
        const url = signedURLArray[0];

        await admin.firestore().collection('...').add({ signedURL: url })
        return null;
    } catch (error) {
        console.log(error);
        return null;
    }

});

另外两个注意事项:

  • 您可以使用Custom Claims云存储安全规则,但不建议在您的情况下使用它们,请参阅here .
  • 您还可以在云存储安全规则中使用文件元数据,但它同样不适合您的情况(您不会在每次新关注者注册时在文件元数据中添加关注者 ID...)

关于基于 Firestore 数据的 Firebase 云存储规则解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67266041/

相关文章:

javascript - 如何使用 NodeJS 在 Firebase 中构建数据

firebase - 我是否正确使用Firestore索引?

ios - 在 flutter 中将 application/octet-stream 转换为 image/jpeg/png?

android - 测试 - 在此过程中未初始化 FirebaseApp

python-3.x - 如何使用谷歌云函数来安排与 python 3.6 一起使用的 python 脚本?

amazon-web-services - BigQuery Transfer Service 不会从 S3 复制行

google-cloud-platform - GCP 警报过滤器不会影响公开事件

swift - 如何在同一个循环中同时循环所有 Firebase 子级?

swift - Firebase Firestore 不更新电子邮件验证状态

ios - Swift 全文搜索推荐解决方案