2015-11-18 35 views
0

我試圖使用Firebase安全規則來防止在我的應用中發生一些不良情況。我此刻的結構是:防止Firebase中出現重複的用戶名

"usernames": { 
    "twitter:123": "jack", 
    "google:456": "bob" 
} 

這裏的問題是,我無法實現安全規則,使得第三用戶(比如facebook:789)不能進來,劫持用戶名「鮑勃」和訪問該用戶的數據(我的數據按用戶名排列)。

這種情況下接受的修復程序是什麼?我試圖扭轉鍵/值對,它允許用戶名唯一的:

"usernames": { 
    "jack": "twitter:123", 
    "bob": "google:456" 
} 

然而,因爲這不強制UID的唯一性,任何用戶都可以發送垃圾郵件的用戶名 - 惡意facebook:789可以採取任何用戶名尚未採取,這將是一個PITA來解決。

有沒有辦法使用Firebase安全規則解決這個困境?或者是受信任的服務器的唯一答案?可信服務器仍然會出現可能的併發問題。

回答

0

好吧,我想我已經明白了。像很多的火力地堡的東西,答案就在於勤奮使用denormalisation :)的

這個解決方案仍然是一個試探性的,所以請不要猶豫,如果你有改正改正/編輯/評論/回答或更好的主意。

用戶名/ uid對需要存儲在兩個格式。由於缺乏一個更好的名字,我叫這個的聯鎖

{ 
    "usernameInterlock" : { 
    "confirm" : { 
     "twitter:123" : "jack" 
    }, 
    "request" : { 
     "jack" : "twitter:123" 
    } 
    } 
} 

這裏有安全規則:

{ 
    "rules": { 
    "usernameInterlock": { 
     "request": { 
      "$username": { 
       ".read": true, 
       ".write": "auth.uid == newData.val() 
       && !(
       data.exists() 
       && root.child('usernameInterlock').child('confirm').child(data.val()).val() == $username 
       )" 
      } 
      }, 
     "confirm": { 
      "$uid": { 
       ".read": true, 
       ".write": "auth.uid == $uid 
       && root.child('usernameInterlock').child('request').child(newData.val()).val() == auth.uid" 
      } 
      } 
    } 
    } 
} 

的過程是:

  1. 用戶將他們的uid/usernameInterlock/request/$desiredUsername。這是可寫除非/usernameInterlock/confirm/$uid_2 == $desiredUsername在這種情況下它屬於$uid_2。任何人都可以請求他們想要的任何用戶名(不管他們想要多少),因爲除非他們在confirm之下,否則他們沒有任何意義。如果有人瘋了,這可以清除。
  2. 用戶然後將$desiredUsername寫入/usernameInterlock/confirm/$uid。只有在適當的request孩子已經填充時才能寫入。然後這成爲確定用戶用戶名的標準方式。

要驗證用戶名,查找/usernameInterlock/request/$username然後查找在/usernameInterlock/confirm/$uid獲得的$uid,並且如果該值$用戶名匹配,則($username, $uid)是一個有效的對。

相關問題