Firebase 安全规则中的临时变量

问题描述 投票:0回答:4

因此,我正在为我的项目设置 Firebase 安全规则,并且为了使用户能够读取房间,我们需要确保他们是该组织的一部分。所以我有一个这样的安全规则:

root.child('organizations').child(data.child('organization_id').val()).child('user_ids').hasChild(auth.uid)

这不仅非常丑陋,同一语句中还有其他几个规则(用 &&/|| 分隔),这些规则以

root.child('organizations').child(data.child('organization_id').val())
开头,用于访问与该房间关联的组织变量中的数据。

这会导致一些丑陋的安全规则,有什么方法可以制作临时变量或类似的东西,这样我就可以使其更具可读性?谢谢!

firebase firebase-security firebase-authentication
4个回答
8
投票

这个问题(以及我在下面的回答)是关于 Firebase 实时数据库及其安全规则。

如果您正在寻找在 Cloud Firestore 或 Cloud Storage 安全规则中使用本地变量,现在是可以实现的。请查看博客文章Firestore 安全规则的新改进有关本地变量的发行说明


实时数据库的 Firebase 安全规则语言不支持自定义变量。这确实导致规则之间存在大量重复。

最好的解决方案是用更高级的语言编写规则,然后编译成 Firebase 安全规则。最著名的是

Blaze(它们的鼻祖)、Butane(不是来自 Firebase 本身)和 Bolt(新的且正在非常活跃的开发中)。

Bolt 例如允许您定义(全局)

函数,它可以轻松封装重复的片段等等。


4
投票
自 2020 年 6 月以来,答案是

是的,您可以拥有局部变量(如果对其他人有帮助,请回答)

来自上面链接的 firebase 博客

局部变量一直是规则中最受欢迎的功能之一,现在它们可以在函数中使用。


1
投票
在 Bolt 中,你可以这样写你的规则:

type Room { organization_id: String, read() { isUserInOrg(this.organization_id) } } isUserInOrg(org_id) { root.organizations[org_id].user_ids[auth.uid] }
    

0
投票
使用模板 json

你好。在检查了上面引用的解决方案后,我认为它们要么无法满足我的需求,要么不再维护。所以我创建了自己的小工具。这包含变量和模板 json。每当对它们进行更改时,实际的规则 json 就会通过组合两者来自动生成。

设置

  1. 在您的 Firebase 项目中创建以下附加文件结构。 database.rules.json 应该已经存在,并且应该链接到您的 firebase.json 中:

    your-project-root/ │ ├── watch-and-generate-rules.js ├── database.rules.template.json ├── database.rules.variables.json ├── database.rules.json (generated & should already exist) │ └── .vscode/ ├── tasks.json └── settings.json
    
    
  2. 安装依赖项:

    npm install chokidar
    
    
  3. 创建

    watch-and-generate-rules.js

    :

    const fs = require('fs'); const path = require('path'); const chokidar = require('chokidar'); const templatePath = path.join(__dirname, 'database.rules.template.json'); const variablesPath = path.join(__dirname, 'database.rules.variables.json'); const outputPath = path.join(__dirname, 'database.rules.json'); function generateRules() { const template = fs.readFileSync(templatePath, 'utf8'); const variables = JSON.parse(fs.readFileSync(variablesPath, 'utf8')); let rulesContent = template; for (const [key, value] of Object.entries(variables)) { const regex = new RegExp(`\\$\\{${key}\\}`, 'g'); rulesContent = rulesContent.replace(regex, value); } fs.writeFileSync(outputPath, rulesContent); console.log('Firebase rules generated successfully!'); } generateRules(); const watcher = chokidar.watch([templatePath, variablesPath]); watcher.on('change', (path) => { console.log(`File changed: ${path}. Regenerating rules...`); generateRules(); }); console.log(`Watching for changes. Press Ctrl+C to stop.`);
    
    
  4. 创建

    .vscode/tasks.json

    :

    { "version": "2.0.0", "tasks": [ { "type": "shell", "command": "node watch-and-generate-rules.js", "isBackground": true, "problemMatcher": [ { "pattern": [ { "regexp": ".", "file": 1, "location": 2, "message": 3 } ], "background": { "activeOnStart": true, "beginsPattern": ".", "endsPattern": "." } } ], "group": "build", "label": "Watch and Generate Firebase Rules", "runOptions": { "runOn": "folderOpen" } } ] }
    
    
  5. 创建

    .vscode/settings.json

    :

    { "task.allowAutomaticTasks": "on" }
    
    
6a。创建最小的示例文件...:

database.rules.template.json

{ "rules": { "users": { "$userId": { ".read": "${READ_ACCESS}", ".write": "${WRITE_ACCESS}" } } } }

database.rules.variables.json

{ "READ_ACCESS": "auth != null", "WRITE_ACCESS": "auth != null && auth.uid == $userId" }
6b。 ...或者您可以直接重构现有的规则文件。只需查看 git 中原始规则文件的状态即可。只要你正确地重构,就不会改变任何事情。将来当你想更改某些内容时,只需编辑模板和变量 json 即可。

© www.soinside.com 2019 - 2024. All rights reserved.