web-dev-qa-db-ja.com

Firebaseセキュリティルールで許可が拒否されましたか?

アプリケーションに適切なセキュリティルールを設定するのに苦労しています。

私が作成しているアプリケーションの概要は、ユーザーがメールとパスワードを使用して自分自身を登録できることです(これには、Firebase Simple Loginを使用しています。これは完全に機能します)。ログインすると、ユーザーは自分のToDoを追加できます。

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

そして、任意のユーザーに対して新しいtodoを追加するには、todosモデルを更新するだけです。

$scope.todos.Push({
   user: '[email protected]',
   todo: 'What to do?'
});

登録されていないユーザーがToDoを追加するのを制限するために使用しているこのセキュリティルール:

  {
    "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: "[email protected]", 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.
13
codef0rmer

Pushは、ランダムに生成されたID(時系列)を持つ新しい子を/todosに追加します。したがって、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: '[email protected]', todo: 'What to do?'});

新しいアイテムがリストに追加されたときのangularFireの動作を最適化するための未解決の問題がありますが、それまでの間、angularFireCollectionを使用して正しい動作を取得できます。

16
Anant