【问题标题】:When correct session name and pin is entered, the response is 'null'输入正确的会话名称和密码后,响应为“空”
【发布时间】:2020-05-05 23:22:03
【问题描述】:

我正在使用 Firebase 实时数据库(使用 Angular 9),并且我需要设置一些规则以仅在用户拥有 PIN 码时才能访问此数据。此外,如果他有 PIN 码,他可以更改它。

这是我的数据库:

sessions
  session_one
    some_data: 'can',
    some_data_2: 'you',
    old_pin: 1234,
    pin: 1234
  session_two
    some_data: 'help',
    some_data_2: 'me',
    old_pin: -1,
    pin: -1
  session_three
    some_data: 'please?',
    some_data_2: 'thanks',
    old_pin: 5555,
    pin: 5555

还有我的规则:

 {
   "rules": {
     "sessions": {
       "$session": {
         ".indexOn": "pin",
         ".read": "query.orderByChild === 'pin' &&
                   query.equalTo === data.child('pin').val()",
         ".validate": "!data.exists() ||
                   newData.child('old_pin').val() === data.child('pin').val()"

       }
     }
   }
 }

我做了一些研究,发现在 Firebase 实时数据库中您无法读取元素的一部分,这里的问题是我想知道具有该键的元素是否存在让我仅在有密码。

例如,我搜索名为“session_three”的会话(如果存在)并且我有我可以读取和修改数据的密码,如果存在并且我没有我无法读取/写入的密码但是我可以知道是否存在,因为如果它不存在,我可以使用该名称创建一个新会话。

角度代码:

this.db.database.ref("sessions/"+this.session).orderByChild('pin').equalTo(this.pin).once('value').then((snap) => {
  this.enterInSession(snap);
}).catch(() => {
  this.db.database.ref('sessions/' + this.inputSession).set({
      some_data: 'loren',
      some_data_2: 'ipsum',
      old_pin: -1
      pin: -1
    }).then(() => {
      this.enterInSession(this.inputSession);
    }).catch(() => {
      this.enterPinDialog();
    });
});

效果很好,问题是在“快照”中,当我输入正确的会话名称和密码时,响应是“空”而不是会话数据。

非常感谢! =)

【问题讨论】:

    标签: javascript firebase firebase-realtime-database firebase-security


    【解决方案1】:

    您需要在查询运行的级别上定义规则。由于您的查询在/sessions 上运行,这也是您需要定义.read 规则的地方。这也立即说明了为什么这种方法不起作用:在/sessions 上,data 将引用所有会话的数据,并且没有 pin 属性来检查其值。

    我发现最容易记住的是,当您附加侦听器时,Firebase 会强制执行其安全规则,并且如果不读取每个单独的文档,它就没有合理的方法来执行它的规则,这不会“扩展”。


    从客户端传递到安全规则的唯一信息是:

    1. 活动用户的auth token
    2. 正在读取/写入的数据的路径。
    3. 如果读取的是查询,则查询中的信息。

    无法将其他自定义信息传递到安全规则中,因此您必须确保该信息属于上述任一信息。

    我对此的常用解决方案是将任何安全信息编码到节点的密钥中。

    sessions
      session_one_1234
        some_data: 'can',
        some_data_2: 'you',
        old_pin: 1234,
        pin: 1234
      session_two_-1
        some_data: 'help',
        some_data_2: 'me',
        old_pin: -1,
        pin: -1
      session_three_5555
        some_data: 'please?',
        some_data_2: 'thanks',
        old_pin: 5555,
        pin: 5555
    

    现在您需要知道原始密钥(例如 session_one 文档的 PIN 才能构建其路径,这是阅读它所必需的。

    与此相关的更简单的规则:

    {
       "rules": {
         "sessions": {
           "$session": {
             ".read": true, // if you know the path, you can read it
           }
         }
       }
     }
    

    只要您不授予用户读取所有/sessions 的权限,他们就不可能找到会话节点的密钥。

    【讨论】:

      猜你喜欢
      • 2015-02-14
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 2020-08-17
      • 1970-01-01
      相关资源
      最近更新 更多