【问题标题】:Adding a token to Firebase Storage for group security将令牌添加到 Firebase 存储以确保组安全
【发布时间】:2020-02-26 20:39:18
【问题描述】:

对于我们的应用,我们需要能够为群组提供文件访问权限。每个用户可以拥有大量的组,因此使用“自定义令牌”解决方案没有意义(无论如何这很尴尬。

我发现,Firebase 的存储安全规则非常有限。主要问题是我们将组定义保留在存储安全规则无权访问的 Firestore 中。

为了克服这个问题,我们决定在每个上传文件的元数据中包含一个“令牌”,该组中的任何人都可以访问该令牌。当他们下载文件时,他们需要在请求参数中提供此令牌(例如 /groups/xxx/filename.jpg?token=abc)。

所以我继续写了这些规则:

match /groups/{groupId}/{filename} {
        allow read: if request.auth != null && request.params.token == resource.metadata.token;
        allow write: if request.auth.uid == userId
                    && request.resource.size < 1 * 1024 * 1024
                    && request.resource.contentType.matches('image/.*')
                    && (resource == null || request.resource.contentType == resource.contentType)
                    && imageId.size() < 32
     ;
}

但是当我在模拟器中运行它时出现错误:“错误:simulator.rules 行 [23],列 [43]。属性参数未在对象上定义。”它指向带有“request.params.token”的规则

文档明确指出我们可以从请求对象访问 params 对象:https://firebase.google.com/docs/storage/security/secure-files?authuser=0#request_evaluation

【问题讨论】:

    标签: firebase firebase-storage firebase-security


    【解决方案1】:

    听起来您正在尝试将 Cloud Firestore 中的一些数据代理到 Cloud Storage 请求中以用于安全规则。目前这是不可行的。 (除此之外,request.params 目前指的是未记录的 API,因此它不能真正使用。我已经向团队提出了这个问题,我们认为 request.params 可能应该从安全规则中删除文档。)

    如果您想为 Firebase 身份验证用户分配可以跨产品(Firestore、存储和实时数据库)验证的组身份,您可以为此使用 custom claims。您需要在后端进行一些工作才能将您要检查的值直接分配给用户帐户。如果操作正确,您在该 JSON blob 中设置的值将显示在 request.auth.token 中的 FirestoreStorage 安全规则中。

    【讨论】:

    • 谢谢,但是当您拥有大量组时,自定义声明将不起作用,因为它被限制为 1000 字节。另外,request.params 是文档(见我的链接)。我觉得你会删除一个功能而不是修复它很奇怪。环顾四周寻找解决方案,如果您希望 Firebase 成为超越 MVP/PoC 的商业上可行的解决方案,允许存储规则查看 Firestore DB 似乎是谷歌开发的一个很好的功能。谢谢。
    • 我认为你误解了我所说的 request.params。我是说它不应该在公共文档中提及,因为它指的是其他也没有记录在案的东西,因此公众通常无法访问。因此,您可以期望它很快会被删除,直到其他功能经过审查和发布。请随时针对当前不可用的任何可以帮助您的情况提出功能请求。 support.google.com/firebase/contact/support
    【解决方案2】:

    由于 Firebase 能够在 Storage 中查询 Firestore 数据的严重限制以及有关 request.param 的不正确文档不可用,我们不得不使用不同的方法。

    我们决定在查询组文件时使用以下 URL:

    /groups/{groupId}/{token}/{filename}

    唯一的安全要求是用户必须登录。由于上述令牌是一个秘密并且只对组成员可用,我们发现它非常安全。我们不允许列出目录,因此无法简单地列出 /groups/{groupId} 来查找任何令牌。

    注意:另一个优化可能是在路径中不包含 {groupId},但我们认为最好包含用于调试和管理目的。

    如果有人觉得这是一种不安全的方式,请在 cmets 上告诉我们!

    谢谢!

    【讨论】:

    • 嗨,同样的问题和类似的解决方案,但我有一个问题:秘密 {token} 需要什么?为什么,在您看来,仅 {groupId} 是不够的,例如 {groupId} 是一个哈希字符串?谢谢。
    • 可能是您想设置一个新密钥(例如,用户离开了群组,不再应该有权访问群组信息)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    • 2012-09-11
    • 2021-09-26
    • 2016-11-02
    • 2018-09-17
    相关资源
    最近更新 更多