2017-06-15 85 views
0

我是Firebase的新手,我正試圖理解使用經過身份驗證的用戶標識來保護數據的規則。我在客戶端上使用Angularfire2。我正在使用電子郵件/密碼認證,這工作正常。如何設置firebase數據庫規則來保護每個用戶的數據?

如果我把我的數據庫規則,允許讀取和寫入認證用戶,一切工作正常,我結束了在火力地堡數據庫中的以下數據...

{ 
    "notes" : { 
    "-KmgjG9hxoXOTtuLTItz" : { 
     "content" : "test", 
     "title" : "Test note 1", 
     "uid" : "iLH4Kg20shViwJebCmU8Ynp0OG23" 
    }, 
    { 
    "-Kmh5igvItrJstbAhRpq" : { 
     "content" : "test", 
     "title" : "Test note2", 
     "uid" : "iLH4Kg20shViwJebCmU8Ynp0OG23" 
    } 
    } 
} 

現在我想限制讀取和寫入其中認證用戶的每個對象上設置的用戶ID(UID)匹配的權限,所以我改變了規則如下......

{ 
    "rules": { 
    "notes": { 
     ".read": "data.child('uid').val() == auth.uid", 
     ".write": "newData.child('uid').val() == auth.uid" 
    } 
    } 
} 

但是,這是行不通的。讀取失敗...

ERROR Error: permission_denied at /notes: Client doesn't have permission to access the desired data.

...和寫入失敗...

FIREBASE WARNING: set at /notes/-KmgjG9hxoXOTtuLTIpG failed: permission_denied

我知道用戶進行身份驗證,因爲如果我硬編碼像規則的用戶ID下面,它工作得很好......

{ 
    "rules": { 
    "notes": { 
     ".read": "auth.uid == 'iLH4Kg20shViwJebCmU8Ynp0OG23'", 
     ".write": "auth.uid == 'iLH4Kg20shViwJebCmU8Ynp0OG23'" 
    } 
    } 
} 
+0

通過您的安全規則,每個用戶都可以訪問他們擁有的每個便條。但是沒有用戶可以獲得筆記列表。這是按照設計工作的,在Firebase條款中稱爲「規則不是裝修者」。我建議閱讀[在Firebase文檔](https://firebase.google.com/docs/database/security/securing-data#rules_are_not_filters)以及其中一個[關於它的許多問題](https:// www.google.com/search?q=site:stackoverflow.com+firebase+rule+are+not+filters),包括[this original one](https://stackoverflow.com/questions/14296625/)。 –

回答

0

我想你忘記了關鍵:

{ 
    "rules": { 
    "notes": { 
     "$key": { 
     ".read": "auth.uid == 'iLH4Kg20shViwJebCmU8Ynp0OG23'", 
     ".write": "auth.uid == 'iLH4Kg20shViwJebCmU8Ynp0OG23'" 
     } 
    } 
    } 
} 

我可能會丟失別的東西,但是您的目標是自動生成的鍵列表(可以在您的規則中用「$ somevar」訪問)。

+0

您說得對,該規則必須在樹中較低才能允許訪問單個筆記。但是從'/ notes'中讀取的內容仍然會隨着您的規則而失敗。 Firebase安全規則不能用於過濾數據。看到我對這個問題的評論的一些鏈接。 –

+0

我試過了。它沒有幫助。 – d60402

+0

@Frank van Puffelen是對的,數據庫規則不是過濾器(你沒有忘記關鍵,但這不是重點)。我記得遇到過這個(煩人的)問題,我用雲功能解決了它的一部分(https://firebase.google.com/docs/functions/)。請參閱https://stackoverflow.com/questions/38687594/firebase-rule-that-works-like-a-filter以開始(它可能會強制您更改您的模式)。 – Rienk

1

我能夠通過重構我的數據模式解決這個問題,將用戶標識放在路徑中,而不是在對象中,例如,使用以下規則...

{ 
    "rules": { 
    "users": { 
     "$userId": { 
      ".read": "$userId === auth.uid", 
      ".write": "$userId === auth.uid" 
     } 
    } 
    } 
} 

根據有關「規則不是過濾器」的意見,我現在明白了。這是絆倒我的事情是在火力地堡數據庫規則文檔指的是「孩子」鍵 - 值對,如...

This example only allows reading if the isReadable child is set to true at the location being read.

".read": "data.child('isReadable').val() == true"

對我來說,意味着JSON數據結構是一樣的東西這...

{ ..., isReadable: true, ...} 

但我想這是指位置路徑,例如,/ users/fred/isReadble或類似的東西。不太確定。這似乎很奇怪。但無論如何,我都能工作。

相關問題