Firebase安全规则导致权限被拒绝?

14

我正在努力为我的应用程序设置适当的安全规则。

我正在编写的应用程序概述是,用户可以使用电子邮件和密码注册自己(我正在使用 Firebase Simple Login 完美地实现此功能)。一旦登录,用户就可以添加他们的待办事项。

angularFire('https://<firebase>/firebaseio.com/todos', $scope, 'todos');

而要针对任何用户添加新的待办事项,我只需要更新待办事项模型即可。

$scope.todos.push({
   user: 'a@b.com',
   todo: 'What to do?'
});

我正在使用这些安全规则来限制未注册用户添加任何待办事项:

  {
    "rules": {
      ".read": true,
      "todos": {
        ".write": "auth != null",
        ".validate": "auth.email == newData.child('user').val()"
      }
    }
  }

但它甚至不允许已验证用户编写任何数据并抛出错误,"FIREBASE WARNING: on() or once() for /todos failed: Error: permission_denied."

但是如果我在模拟器中添加以下数据,则可以按预期工作。

{user: "a@b.com", todo: 'What to do?'} 

这是日志:

/todos:.write: "auth != null"
    => true
/todos:.validate: "auth.email == newData.child('user').val()"
    => true
/todos:.validate: "auth.email == newData.child('user').val()"
    => true

Write was allowed.

你可以尝试使用Forge中的安全模拟器来查看为什么这不起作用。两个注释:1)您似乎正在编写一个只有一个对象的数组,它可能应该只是一个对象。2)"$todos"变量可能只需要是"todos"。 - Anant
@Anant:感谢您的回复。正如您所说,我删除了$符号,并将验证规则更改为".validate": "auth.email == 'a@b.com'",其中a@b.com是已注册的用户 - 这个方法可行,但是".validate": "'a@b.com' == newData.child('user').val()"不行。是否有可能查看newData的内容? - codef0rmer
@Anant:我更新了问题以便让您更清楚。正如您所说,$ 不是必需的,那么为什么在文档中到处都使用它呢? - codef0rmer
可能存在时间问题 - 即在完成身份验证之前,您正在尝试推送数据。您是使用 angularFireAuth 进行身份验证,还是通过 FirebaseSimpleLogin 手动进行身份验证? - Anant
"$"在文档中被用作变量,即当您不知道该节点的值时。在您的情况下,“todos”是一个固定常量,因此您不需要“$”,但您需要一个子元素,如“$todoid”,或者只需“$id”来引用自动生成的推送对象。 - Anant
1个回答

17

push操作会按照时间顺序为/todos路径下添加一个带有随机生成ID的新子节点。因此,newData并不是指向您认为的内容。请将您的规则更改为:

{
  "rules": {
    ".read": true,
    "todos": {
      "$todoid": {
        ".write": "auth != null",
        ".validate": "auth.email == newData.child('user').val()"
      }
    }
  }
}

更新:上述规则仍有效,但是angularFire当前会将整个数组写回服务器,导致身份验证失败。您可以改用angularFireCollection,仅将新的TODO写回服务器,操作如下:
$scope.todos = angularFireCollection(new Firebase(URL));

$scope.todos.add({user: 'a@b.com', todo: 'What to do?'});

已经有一个未解决的问题需要优化angularFire在添加新项目到列表时的行为,但与此同时您可以使用angularFireCollection来获取正确的行为。


1
问题出在 angularFire 上,我在 firebase-talk 邮件列表上发布了一个解决方法(使用 angularFireCollection.add 代替)。 - Anant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接