繁体   English   中英

Firebase 实时数据库规则在前端不起作用

[英]Firebase Realtime Database rules not working in frontend

具体的TLDR:规则".read": "auth != null && data.child('userEmail').val() === root.child('users').child(auth.uid).child('email').val()"应该在应用程序中按预期工作。

我已经按照文档和规则操场进行了测试,所以我认为这可能与我进行身份验证的方式有关? 我将在下面提供信息,希望有人能尽快回答。

实时数据库结构:

"db-name": {
  "units": {
    0: {
      "serial": "002",
      "userEmail": "s@gmail.com"
    },
    1: {
      "serial": "001",
      "userEmail": "r@gmail.com"
    }
  },
  "users": {
    "R6nlZ...": {
      "email": "r@gmail.com"
    },
    "qwerty...": {
      "email": "s@gmail.com"
    }
  }
}

规则对象:

{
  "rules": {
    // ".read": "now < 1604037600000",  // 2020-10-30
    // ".write": "now < 1604037600000",  // 2020-10-30
    "units": {
      ".indexOn": "userEmail",
      "$key": {
        ".read": "auth != null && data.child('userEmail').val() === root.child('users').child(auth.uid).child('email').val()",
        ".write" : "auth != null && data.child('userEmail').val() === root.child('users').child(auth.uid).child('email').val()"
      }
    },
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

规则测试:模拟类型:读取 位置:https:db-name.firebaseio.com/units/1 经验证:是 提供者:匿名 UID:R6nlZ... 结果:允许模拟读取

如果我试图让/units/0我得到否认这是我所期望的,因为这是一个unit ,目前auth'd用户没有权限查看。

现在,如果我使用纯 javascript 执行此操作,则不会得到与在 Firebase 控制台中的规则操场中所做的相同的结果。

<!-- Add the entire Firebase JavaScript SDK -->
    <script src="https://www.gstatic.com/firebasejs/7.24.0/firebase.js"></script>

    <script>
    // import * as firebase from "firebase";
    var firebaseConfig = {
      apiKey: "...",
        authDomain: "...",
        databaseURL: "...",
        projectId: "...",
        storageBucket: "...",
        messagingSenderId: "...",
        appId: "..."
    };
    // Initialize Firebase
    firebase.initializeApp(firebaseConfig);

    var email = 'r@gmail.com';
    var password = '123456';
    // Sign in existing user
    firebase.auth().signInWithEmailAndPassword(email, password).then(function() {
      console.log('Signed in as: ' + firebase.auth().currentUser.email);

      var dbUnits = firebase.database().ref().child('units').orderByChild('userEmail').equalTo(firebase.auth().currentUser.email);
      var getUnitsDetails = function() {
        return dbUnits.once('value').then(function(snapshot) {
          snapshot.val() ?
          Object.entries(snapshot.val()).map((unit) => {
            return (
              console.log('Serial number of unit: ' + unit[1].serial + ' & Owner of unit: ' + unit[1].userEmail)
            )
          })
          :
          console.log('no units found for that user bro')

        })
      }
      console.log(getUnitsDetails());


    }).catch(function(error) {
      console.log(error);
    });

当我在粘贴的规则中设置了 Firebase 权限时,用户r@gmail.com看不到任何单位。 如果我让读取权限完全打开(不是我想要的),那么该用户可以看到他们的单位。

对我来说这没有意义,因为我认为auth.uid是 Firebase 在用户登录时可以看到的内容,无论他们使用什么登录类型。

您的规则不允许此查询:

firebase.database().ref().child('units').orderByChild('userEmail').equalTo(firebase.auth().currentUser.email);

要使此查询起作用,用户需要对/units具有读取权限。 由于您没有在/units上声明任何.read规则,因此查询被拒绝。

您似乎认为规则会过滤数据以仅返回用户应该有权访问的数据,但这不是它们的工作方式。 正如 Firebase 文档所说: 规则不是过滤器

但是安全规则可以与查询结合使用,以安全地允许查询数据。

在你的场景中,看起来像:

{
  "rules": {
    "units": {
      ".read": "auth.uid != null &&
                query.orderByChild == 'userEmail' &&
                query.equalTo == auth.token.email"
      ...

现在您的查询将被允许,而/users其他/更广泛的读取将被拒绝。

"$key": {
        ".read":   "auth !== null && root.child('users').hasChild(auth.uid)",
        ".write" : "auth !== null && root.child('users').hasChild(auth.uid)"
}

这样写的任何存在于用户集合中的用户都可以访问“单位”

或者,您可以使用该用户的 uid 进行收集,并将密钥与他的 uid 匹配以进行访问

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM