当前位置: 首页 > 知识库问答 >
问题:

具有多个子节点的节点的Firebase安全规则

单于皓轩
2023-03-14

我当前的firebase结构如下所示

本来我的保安看起来

{
    "rules": {
        "users": {
            "$companyId": {
                "$userId": {
                    ".read": "auth != null",
                    ".write": "auth != null",
                }
            }
        }
    }
}

这一切都很好,因为我可以通过

// get user information from database
getUserInformation(companyId: string, uid: string) {
    let path = '/users/' + companyId + '/' + uid;
    return this.af.database.object(path, { preserveSnapshot: true })
}

然而,我想给这个分支增加更多的安全性,这样用户就不能通过写操作(读取是可以的)更新前端的代码来修改其中的一些条目。我希望用户能够根据isAdmin标志修改这些条目,例如,

  1. companyId(读:auth!=null,写:isAdmin==true)

因为所有读取=auth!=无效的起初,我认为因为我能够读取所有节点,所以我可以为每个节点设置单独的安全规则,如下所示

{
    "rules": {
        "users": {
            "$companyId": {
                "$userId": {
                    "companyId": {
                        ".read": "auth != null",
                        ".write": "(auth != null) && (root.child('users').child($companyId).child(auth.uid).child('isAdmin').val() == true)"
                    },
                    "isAdmin": {
                        ".read": "auth != null",
                        ".write": "false"
                    },
                    "lastLoggedIn": {
                        ".read": "auth != null",
                        ".write": "auth != null"
                    },
                    ...
                }
            }
        }
    }
}

但是,当我尝试getUserInformation()时,这失败了,因为我正在查询“/users/'companyId'/”uid,并且该特定分支的安全规则未知

我猜作为一种选择,我可以查询每个节点,而不是'/用户/'公司ID'/'uid'/公司ID',并使用forkJoin或某种排序组合数据。这将是非常无效的,因为我现在是第n次调用数据库,而不是一次。

我能想到的另一种方法是,通过将数据分为三个分支“userCanModify”、“adminCanModify”、“noOnCanModify”,以不同的方式构造数据。然后根据需要为这三个节点设置安全规则。但这在我看来更像是一种黑客行为,因为我必须将数据重新构造为一种非常奇怪的格式。此外,我还需要提出三个请求才能全面了解用户的详细信息

{
    "rules": {
        "users": {
            "$companyId": {
                "$userId": {
                    "userCanModify": {
                        "lastLoggedIn": {
                            ".read": "auth != null",
                            ".write": "auth != null"
                        },
                        ...
                    }, 
                    "adminCanModify": {
                        "companyId": {
                            ".read": "auth != null",
                            ".write": "(auth != null) && (root.child('users').child($companyId).child(auth.uid).child('isAdmin').val() == true)"
                        }, 
                        "companyName": {
                            ".read": "auth != null",
                            ".write": "(auth != null) && (root.child('users').child($companyId).child(auth.uid).child('isAdmin').val() == true)"
                        },
                        ...
                    }, 
                    "noOneCanModify": {
                        "isAdmin": {
                            "read": true, 
                            "write": false
                        },
                        ...
                    }
                }
            }
        }
    }
}

有没有一个更好的解决方案,我错过了?

共有1个答案

南宫奇思
2023-03-14

你试过这个安全规则语法吗?:

 {
    "rules": {
        "users": {
            "$companyId": {
                "$userId": {
                    "$companyIdbis": {
                        ".read": "auth != null",
                        ".write": "root.child('users').child($companyId).child($userId) === auth.uid &&  data.child('isAdmin').exist()"
                    },

                    "isAdmin": {
                        ".read": "auth != null",
                        ".write": "false"
                    },
                    "lastLoggedIn": {
                        ".read": "auth != null",
                        ".write": "auth != null"
                    },
                    ...
                }
            }
        }
    }
}

(如果我没有错:

data.child('isAdmin').exist()"

应等同于:

  `root.child('users').child($companyId).child($userId).child($companyIdbis).child('isAdmin').exist()"`

[编辑]:但我建议您采用“扁平结构”,将用户和公司喜欢的节点分开:

Users
    userId
        compagnyId : true
        etc ...
Compagnies
    compagnyId
        etc ...

这允许您检索用户列表,而无需浏览所有compagnies节点

 类似资料:
  • 我已经实现了一个TreeModel来调整存量数据模型,以便将其可视化为JTree。我遇到了一个问题,节点有多个相同的子(叶)节点。例如,考虑一个JTree,它的叶节点是Strings。每当父节点包含具有相同String值的子节点时,就会出现问题。这些叶节点的TreePath是相同的,作为Strings,equals()返回true。留档明确地调用这个: JTree及其相关类广泛使用TreePath

  • 我有一个XML文档,它包含一个非常复杂(对我来说)的结构,没有换行符。它有许多具有类似结构的元素: 我需要得到节点值的文本,这是节点成员的孩子也有孩子的名字与特定的文本(在这种情况下virtual_size)。也有可能存在几个类似的节点。我可以用[1]etc吗? 这让我知道了节点的名称,但是如何达到“值”节点呢?

  • 我正在尝试做一个使用组合键的场景。我想有更多的公钥,这样我就可以用其中任何一个密钥来签署一个txn。 该场景的参考如下:https://docs.corda.net/api/kotlin/corda/net.corda.core.crypto/-composite-key/index.html 根据我的理解,deployNodes任务使用单个公钥生成节点。如果我偏离了轨道,请纠正我。

  • 我试图在一个有几个嵌套动态子节点的数据模型中实现Firebase rules read限制。 我有以下数据模型:

  • 我有一个SVG文档,其中包含类似于以下内容的节点: 我想做的只是选择

  • 无法完成这项理论上相对简单的任务: 查找节点文档,其中Field具有包含特定文本的属性Name,并且子节点Option具有值。 XML: 所以我希望能够将模板应用到文档中,比如 但那是行不通的。 只需指定:文档必须在选项中包含文本,该选项是包含特定文本的字段的子节点。 在xml中,使用输入值: 1:Børn Fridslip= 2: Børn-Fritidsklub= 3:Børn Fritid=