如何在没有身份验证的情况下添加 Firebase 数据库规则?

Posted

技术标签:

【中文标题】如何在没有身份验证的情况下添加 Firebase 数据库规则?【英文标题】:How to add firebase database rules without authentication? 【发布时间】:2021-09-25 07:16:09 【问题描述】:

我想添加 Firebase 实时数据库规则,它设置为默认值,我不能使用身份验证,因为我的应用程序已经部署了数据库中的数据。

请帮忙,谢谢

【问题讨论】:

保留默认规则。使用安全规则不是强制性的。但是,您的数据库仍然不安全,一些恶意用户可能会利用这一点。 @alexmamo 我认为至少应用验证规则并限制某些数据库节点会减少滥用的途径——尽管身份验证不一定是这些规则的一部分。 @samthecodingman 是的,确实是山姆。 【参考方案1】:

要授予任何用户对您的实时数据库 (RTDB) 的完整读/写访问权限,您可以使用以下全局读/写访问规则:


  "rules": 
    ".read": true,
    ".write": true
  

这些规则将允许任何人读取、写入、删除或更改您数据库中的数据 - 包括删除整个数据库。这些规则还会触发来自 Firebase 的定期电子邮件,警告您您的规则不安全。


您可以通过多种方式来收紧数据库以防止此类滥用,而不是使用如此广泛的规则。

Firebase 安全规则是documented here,它们的API reference is here,您可以manage them here。

因为您已表明您不打算使用 Firebase 身份验证,所以我将省略这些示例,而是请您参阅这些示例的文档。由于您没有提供任何存储在数据库中的数据示例,因此我还将提出各种有关将汽车存储在数据库中的示例。


假设您的应用包含一个可公开访问的汽车数据库,该数据库位于 /cars 下,具有以下形状:

interface Car 
  make: string,
  model: string,
  year: number,
  type: string

我们可以不使用上面完全公开的规则,而是让用户只能读取/写入/cars 节点:


  "rules": 
    "cars": 
      ".read": true,
      ".write": true
    
  

通过上述规则,您可以创建、更新、删除/cars 下的任何节点,但对/trains 的读/写将被拒绝。这是因为除非另有定义,否则安全规则默认为false(拒绝)。如果安全规则会引发错误(语法错误、丢失数据、错误对象类型),则将其视为false(拒绝)。

通过上述规则,任何用户都可以创建/cars/someId/path 并在其中填充大量不相关的数据。

为了纠正这个问题,我们可以在动态节点路径下定义节点(例如cars/$carId)并选择哪些字段可以读/写:


  "rules": 
    "cars": 
      // any car is readable
      ".read": true,

      "$carId": 
        "make":   ".write": true ,
        "model":  ".write": true ,
        "year":   ".write": true ,
        "type":   ".write": true 
      
    
  

使用这些规则,您现在可以在数据库中创建和存储Car 对象。您将无法将数据添加到像 /cars/someId/path 这样的位置,但您仍然可以像以前一样将数据添加到 /cars/someId/make/path

这就是数据验证规则的用武之地。我们可以确保节点的类型是我们所期望的(只要它是数字、字符串或布尔值):


  "rules": 
    "cars": 
      // any car is readable
      ".read": true,

      "$carId": 
        "make":   ".write": true, ".validate": "newData.isString()" ,
        "model":  ".write": true, ".validate": "newData.isString()" ,
        "year":   ".write": true, ".validate": "newData.isNumber()" ,
        "type":   ".write": true, ".validate": "newData.isString()" 
      
    
  

上述规则强制Car 对象的每个部分的类型,但它们不能确保整个Car 对象都存在。为了对节点的子节点强制执行验证,例如确保存在整个汽车对象,我们将".validate" 规则上移一级:


  "rules": 
    "cars": 
      // any car is readable
      ".read": true,

      "$carId": 
        // a car object must be complete
        ".validate": "newData.child('make').isString() && newData.child('model').isString() && newData.child('year').isNumber() && newData.child('type').isString()",

        "make":   ".write": true ,
        "model":  ".write": true ,
        "year":   ".write": true ,
        "type":   ".write": true 
      
    
  

通过上述规则,您现在可以创建/更新/删除存储在/cars 下的任何汽车,只要它们看起来像Car 对象即可。


仅仅允许完全的写访问可能不是您想要的。通过调整".write": "true",我们可以对允许更改的数据应用额外的限制。

如果我们想让你只能创建/更新汽车,但不能删除它,我们可以使用:

".write": "newData.exists()"

如果我们想让你只能创建汽车,但不能更新/删除它,我们可以使用:

".write": "!data.exists()"

如果我们想让你只能更新现有的汽车,但不能创建/删除它,我们可以使用:

".write": "data.exists() && newData.exists()"

使用这些构建块,您现在应该能够在不阻塞现有应用程序的情况下收紧数据库。

【讨论】:

你杀了我。很好的答案,山姆!

以上是关于如何在没有身份验证的情况下添加 Firebase 数据库规则?的主要内容,如果未能解决你的问题,请参考以下文章

在没有 Firebase 身份验证的情况下保护 Firebase 数据库

如何在不使用 Firebase 身份验证的情况下保护 Firebase 存储? (下一个)

如何在启用电话身份验证的情况下导出 Firebase 用户帐户

如何在视图模型中实现 Firebase 电话身份验证?

如何在不关闭当前 Firebase 会话的情况下创建用户身份验证 [重复]

在不使用 Firebase 的情况下使用电子邮件和密码进行 Flutter 身份验证