2015-11-18 40 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)是一个有效的对。

相关问题