基于 Firestore 数据的 Firebase 云存储规则可以解决

Posted

技术标签:

【中文标题】基于 Firestore 数据的 Firebase 云存储规则可以解决【英文标题】:Firebase Cloud Storage rules based on Firestore Data work around 【发布时间】:2021-07-19 19:00:17 【问题描述】:

在我的 firebase 应用中,我有

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

我希望只有关注者能够阅读用户的头像,我在云存储中添加了如下规则:

match /profilePhotos/profilePhotoFile_id 

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


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

【问题讨论】:

【参考方案1】:

我是否正确假设只有登录的用户 并且也是追随者将能够阅读的个人资料照片 另一个用户?

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

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


一种可能的方法是使用Cloud Function 生成一个签名 URL,您将其存储在 Firestore 文档中AND 以禁止读取配置文件照片文件。由于 Cloud Functions 使用 Admin SDK,它们可以绕过安全规则。

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

您可以通过以下方式使其适应您的情况:

    如有必要,只处理头像(检查文件名是否包含profilePhotos) 将 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...)

【讨论】:

谢谢,@RenaudTarnec 的回答,如果我要使用需要明确给予列表权限的规则版本 1。如果我不允许列表权限,那么这个问题就可以解决了吗? 是的,List API 仅适用于规则版本 2。因此您可以依赖于版本 1 无法实现这一事实。 但是,一般来说,不建议将安全策略建立在假设没有人可以猜测文件路径(或云存储 gs://... 在我们的例子中的 URL)的假设上......

以上是关于基于 Firestore 数据的 Firebase 云存储规则可以解决的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Firestore - 基于“where”查询参数的安全规则

Firestore/Firebase - 为关注/关注用户帖子建模数据的方法

SwiftUI UserDefaults 干扰 Firebase Firestore 数据

SwiftUI Lists + Firebase Firestore,获取数据然后取消获取? (漏洞)

基于角色的 Firestore 规则

如何使用 Firestore 运行地理“附近”查询?