Firebase auth()成功,但检查登录状态的安全规则仍然失败

时间:2013-03-31 13:08:11

标签: firebase

当我使用".read": "auth != null"时,ref.on()会在ref.auth()完成后无错误地引发权限错误。只要用户登录,授予读取权限的正确方法是什么?

安全规则:

{
  "rules": { 
    ".read": "auth != null",
    ".write": "auth.admin == true"
  }
}

以下是在我执行“on()”之前返回Firebase参考的代码:

    ref: function(path) { var self = this;
      var ref = new Firebase(self.url + path);
      ref.auth(self.auth_token, function(err) {
        if (err && console) console.log("Firebase "+path+" login failed!");
        else if (console) console.log("Firebase "+path+" login succeeded.");
      });
      return ref;
    },
    bind: function(path, excludes) { var self = this;
      var collection = [];
      var ref = self.ref(path);
      ...
      var move_callback = function(data, prevId) { 
        $timeout(function() { moveItem(data, prevId); }); 
      }
      ref.on('child_added', move_callback);
      ref.on('child_changed', move_callback);
      ref.on('child_moved', move_callback);
      ref.on('child_removed', function(data) {
        $timeout(function() { removeItem(data); });
      });
      return collection;
    },

MAIN控制器:

$scope.list = $$firebase.bind("/data", []);

控制台说

Firebase /data login succeeded. app.js:298
FIREBASE WARNING: on() or once() for /data failed: permission_denied firebase.js:33

1 个答案:

答案 0 :(得分:2)

我从您的代码中不清楚您在auth完成后返回引用。具体做法是:

ref: function(path) {
  var self = this;
  var ref = new Firebase(self.url + path);
  ref.auth(self.auth_token, function(err) {
    if (err && console) console.log("Firebase "+path+" login failed!");
    else if (console) console.log("Firebase "+path+" login succeeded.");
  });
  return ref;
}

立即返回引用。对auth的回调是异步的,所以如果你在调用回调之前使用你的ref,你的会话将是未经身份验证的。

看起来你正在使用Angular,所以我发了一个小例子,它正确地使用了与你相同的安全规则:https://gist.github.com/anantn/5304404

如果我要重写你的代码,我会按如下方式进行:

bind: function(path) {
  var ref = new Firebase(self.url + path);
  var d = self._q.defer(); // Assign $q to this._q in constructor.
  ref.auth(self.auth_token, function(err) {
    if (!err) {
      ref.once("value", function(snap) {
        d.resolve(snap.val());
      });
    }
  });
  return d.promise;
}
...
// In the controller:
$scope.list = $$firebase.bind("/data");

我强烈建议您通过$ q模块使用promises,以确保在auth完成之前不使用Firebase参考。更好的解决方案是使用Angular的官方Firebase绑定,它已经为您完成了所有这些:https://github.com/firebase/angularFire

希望这有帮助!