1

学ぶために、roder で backbone.js を使用してアプリを書いています。私が実際に得たものはこちらにあります: https://the-todo-app.firebaseapp.com/

私の考えは、人々がfacebookでsimpleLoginを使用してアプリに登録してユーザーを作成できるようにすることです。その後、ユーザーにリダイレクトされ、todosを作成および変更できますが、実際にはすべてのユーザーが書き込む可能性があるという問題がありますつまり、他のユーザーのデータを入力したり、削除または変更したりできます。Firebase のセキュリティを制限して、ID に基づいてユーザーを作成できるようにしたいのですが、認証されていない場合は書き込みを許可しません。これは私が実際に持っているものです:

{
  "rules": {
    ".read": true,
    ".write": true,
    ".validate": "data.hasChildren(['name', 'picture'])",
    "users": {
      "$user": {
        ".read": "$user == auth.id",
        ".write": "$user == auth.id"
      }          
    }
  }
}

麻生はこれを試しました:

{
  "rules": {
    ".read": true,
    "users": {
      "$user": {
        ".read": "$user == auth.id",
        ".write": "$user == auth.id"
      }          
    }
  }
}

ただし、このアプローチでは、クライアントがユーザー ID を作成することはできません。

これは私のデータが実際にどのように見えるかです:

{
  "users" : {
    "10152111176005069" : {
      "name" : "Jhonnatan Gonzalez Rodriguez",
      "picture" : "url to pic"
    },
    "10154397958535078" : {
      "name" : "Diana Rincón P",
      "picture" : "url to pic"
    },
    "10152167159946759" : {
      "name" : "Sebastian Ayala",
      "picture" : "url to pic"
    }
  },
  "title" : "The todo app"
}

皆さんがこれを行う方法についての考えを持っているなら、私は感謝します。

ArneHugo の回答に基づいて、このルールを設定したところ、かなりうまく機能しているようです。確認するには、さらにテストを行う必要があります。

{
  "rules": {
    "users": {
      ".write": "!data.child(auth.id).exists()",
      "$user": {
        ".read": "$user == auth.id",
        ".write": "$user == auth.id",
        ".validate": "newData.hasChildren(['name', 'picture'])"
      }          
    }
  }  
}

実際には、ユーザーがデータが存在するかどうかを確認できるようにするために、ユーザーに .read ルールを true に追加する必要がありました。これが現在のルールの外観です。

{
  "rules": {
    "users": {
      ".read": "true",
      ".write": "!data.child(auth.id).exists()",
      "$user": {
        ".read": "$user == auth.id",
        ".write": "$user == auth.id",
        ".validate": "newData.hasChildren(['name', 'picture'])"
      }          
    }
  }  
}

そして、これは出力が匿名ユーザーをどのように探すかです

Attempt to write {"id":"6726363"} to /users/6726363 with auth=null
    /
    /users:.write: "!data.child(auth.id).exists()"
5:30: child() expects a string argument.
        => false
    /users/6726363:.write: "$user == auth.id"
        => false
    /users/6726363:.validate: "newData.hasChildren(['name', 'picture'])"
        => false

Validation failed.
Write was denied.

そして、これが認証されたユーザーを探す方法です。

Attempt to write {"name":"6726363","picture":"fb picture"} to /users/6726363 with auth={"id":"6726363"}
    /
    /users:.write: "!data.child(auth.id).exists()"
        => true
    /users/6726363:.validate: "newData.hasChildren(['name', 'picture'])"
        => true
    /users/6726363:.validate: "newData.hasChildren(['name', 'picture'])"
        => true

Write was allowed.

これは、別のユーザー データを書き込もうとしている匿名ユーザーの uoutput です。

Attempt to write {"name":"6726363","picture":"fb picture"} to /users/10152111176005069 with auth=null
    /
    /users:.write: "!data.child(auth.id).exists()"
5:30: child() expects a string argument.
        => false
    /users/10152111176005069:.write: "$user == auth.id"
        => false
    /users/10152111176005069:.validate: "newData.hasChildren(['name', 'picture'])"
        => true

No .write rule allowed the operation.
Write was denied.

さて、この例を作成すると、データベースに存在する ID を持つ認証されたユーザーが、このように別のユーザー データを書き込むことができることがわかりました。

Attempt to write {"name":"6726363","picture":"fb picture"} to /users/10152111176005069 with auth={"id":"6726363"}
    /
    /users:.write: "!data.child(auth.id).exists()"
        => true
    /users/10152111176005069:.validate: "newData.hasChildren(['name', 'picture'])"
        => true
    /users/10152111176005069:.validate: "newData.hasChildren(['name', 'picture'])"
        => true

Write was allowed.
4

1 に答える 1

3

あなたがやりたいことは完全に可能であり、別の種類のログインを使用する必要があるという Kato の意見には同意しません。

必要なのはこれだけです:

  "rules": {
    "users": {
      //".write": "!data.exists()", /* Edit: removed, as it always returned false */
      "$user": {
        ".read": "$user == auth.id",
        ".write": "$user == auth.id",
        ".validate": "newData.hasChildren(['name', 'picture'])"
      }          
    }
  }
  1. 新しいユーザーは、自分用に $user エントリを追加できます。
  2. ユーザーは自分以外の $user から読み取ることはできません。
  3. ユーザーは自分以外の $user に書き込むことはできません (有効なエントリを保証する最初の場所で $user を作成する場合を含みます)。
  4. $user エントリには、名前と画像が必要です。(検証ルールを移動したことに注意してください。)

ヒント: Firebase のシミュレーターを使用して、セキュリティ ルールをテストします。シンプルで素晴らしいツールです。

編集

データが存在するかどうかを確認するために読み取りルールが本当に必要かどうかを確認するテストを行いました。(答え:あなたはしません。)

次のセキュリティ ルールで

"test": {
    ".write": "!data.child(auth.id).exists()",
    "$user": {
        ".validate": "newData.hasChildren(['name', 'picture']) && $user == auth.id",
        ".read": "$user == auth.id",
        ".write": "$user == auth.id"
    }          
}

新しいユーザーを書き込もうとしました:

Attempt to write {"name":"Beardinator","picture":"i.imgur.com/axXz9sr.jpg"} to /test/1337 with auth={"id":"1337"}
    /:.write: "root.child('adminPanel').child('admins').child(auth.uid).val() != null"
20:67: child() expects a string argument.
        => false
    /test:.write: "!data.child(auth.id).exists()"
        => true
    /test/1337:.validate: "newData.hasChildren(['name', 'picture']) && $user == auth.id"
        => true
    /test/1337:.validate: "newData.hasChildren(['name', 'picture']) && $user == auth.id"
        => true

Write was allowed.

私のテストでは、「ユーザー」の .read ルールなしでデータが正常に存在するかどうかを確認できます。

于 2014-07-19T12:18:56.397 に答える