2017-02-14 9 views
0

私はFirebaseを使用して作成しているiOSアプリケーションで、各ユーザーは電子メールとパスワードでサインアップした後に作成される固有のユーザー名を持っています。&&と||を持つこのFirebaseデータベースセキュリティルールはなぜですか? not working

ので[email protected]の電子メールを持つユーザーがサインアップし、その後、次のようにデータベースのスニペットは次のようになり、ユーザ名データベースにないユニークなユーザ名を作成するために持っていた場合:

"usernames" : { 
     "test" : "r6KPesUr1qORfIJke07SloZHeNW2", 
     "test1" : "jSMSkY9rHtdNkXoLrsFmCAXdY9n2", 
     "test7" : "jnFhJbgCjZeJFx0hspObqoskQej2", 
     "test8" : "HtnULzU0lnZKYva2M2Wepl6N8wE3" 
    }, 

    "users" : { 
     "HtnULzU0lnZKYva2M2Wepl6N8wE3" : { 
      "email" : "[email protected]", 
      "username" : "test8" 
     }, 
     "boX6rtJ98haWVxNoXfSq21maCVU2" : { 
      "email" : "[email protected]" 
     }, 
     "jSMSkY9rHtdNkXoLrsFmCAXdY9n2" : { 
      "email" : "[email protected]", 
      "username" : "test1" 
     }, 
     "jnFhJbgCjZeJFx0hspObqoskQej2" : { 
      "email" : "[email protected]", 
      "username" : "test7" 
     }, 
     "r6KPesUr1qORfIJke07SloZHeNW2" : { 
      "email" : "[email protected]", 
      "username" : "test" 
     } 
    } 

私は、ユーザーがサインアップを完了したときにユーザー名が一意であることを確認するために、次のセキュリティ規則を用意しています。検証ルールについては

// USERNAMES 
    "usernames": { 
     ".read": "auth.uid != null", 
     ".write": "auth.uid != null", 
     "$username": { 
      ".validate": "(!root.child('usernames').hasChild($username.toLowerCase()) && newData.val() == auth.uid && 
          root.child('users').hasChild(auth.uid)) && 

          (root.child('users/'+auth.uid+'/username').val().toLowerCase() == $username || 
          !root.child('users/'+auth.uid+'/username').exists())"     
     }         
    } 

(!root.child('usernames').hasChild($username.toLowerCase()) && 
    newData.val() == auth.uid && 
    root.child('users').hasChild(auth.uid)) 

これら二つの文でそれらのいずれかに該当

"(root.child('users/'+auth.uid+'/username').val().toLowerCase() == $username || 
    (!root.child('users/'+auth.uid+'/username').exists()" 

もしそうならなければならないがぐるぐるしなければならないと私は、これらの3つの文を持っていると思いますユーザーはtest5にサインアップしたかったので、次のjsonにユーザー名を入力すると、最初の部分のために現在のセキュリティールールでは機能しませんORステートメント。

 "users": { 
     "boX6rtJ98haWVxNoXfSq21maCVU2": { 
       "username": "test5" 
      } 
    } 

私は間違っていますか?

+0

ルールを解析するのは非常に難しいです。この検証ルールで拒否される最小限のコードを含めるように質問を編集できますか? –

+0

@FrankvanPuffelen確かに。私は、データベースがどのように見えるのか、そしてその後[email protected] – Edward

+0

のメールでユーザの一意のユーザ名を作成するために書かれていないjsonを追加しました。あなたのユースケースを理解しようとしました。しかし、このような複雑なルールから理解するのは難しいので、私は1つ(よく2つ)の特定のユースケースを分離し、それに焦点を当てました。 –

答えて

1

あなたは二つのことは、ユーザー名を主張するユーザーのために起こるしたいように思え:

  1. ノードは、ユーザー名
  2. /users/$uid/usernameの下に書かれているノードは自分のUIDと/usernames/$usernameの下に書かれています

あなたが今作成したJSONスニペットには#1しか含まれていません。 /usernamesの下にユーザー名を書くことについては何も書かれていません。したがって、ユーザー名が存在し、そのユーザーに対して要求されていることを検証しているため、ルールはそれを拒否します。

おそらく、#1、#2のようなマルチロケーション更新されるであろう、同時に起こることを検証する:あなたのルールは以下のようになり

"users/boX6rtJ98haWVxNoXfSq21maCVU2/username": "test5", 
"usernames/test5": "boX6rtJ98haWVxNoXfSq21maCVU2" 

"usernames": { 
    "$username": { 
    ".validate": "!data.exists() && 
     newData.exists() && 
     newData.parent().parent().child('users').child(auth.uid).child('username').val() === $username" 
    }         
} 
"users": { 
    "$uid": { 
    "username": { 
     ".validate": "!data.exists() && 
     newData.exists() && 
     newData.parent().parent().parent().child('usernames').child(newData.val()).val() === $uid" 
    } 
    } 
} 

小文字の部分は削除しました。これは、コード内でそれを修正し、小文字のユーザー名のみを保存する方が簡単だからです。

+0

「ユーザー」と「ユーザー名」の両方の終了規則については、括弧をnewData()から削除する必要があると思います。 – Edward

+0

私はそこに何を意味するのか分かりません。しかし、編集を提案することは自由に感じてください。 –