防止Firebase中出现重复的用户名

时间:2015-11-18 06:34:43

标签: security firebase

我正在尝试使用Firebase安全规则来防止在我的应用中发生许多不良情况。我目前的结构是:

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

这里的问题是我无法实现安全规则,以至于第三个用户(比如facebook:789)无法进入并劫持用户名'bob'并访问该用户的数据(我的数据)由用户名安排。

此方案的可接受修复是什么?我试过反转键/值对,这允许用户名的唯一性:

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

然而,由于这不强制UID的唯一性,任何用户都可以垃圾邮件用户名 - 恶意facebook:789可以使用任何尚未使用的用户名,这将是PITA的整理。

有没有办法使用Firebase安全规则解决这个难题?或者是受信任的服务器的唯一答案?可信服务器仍会出现可能的并发问题。

1 个答案:

答案 0 :(得分:0)

好的,我想我已经知道了。像Firebase中的很多东西一样,答案在于勤奋使用非规范化:)

这个解决方案仍然是一个暂定,所以如果你有更正或更好的想法,请不要犹豫,纠正/编辑/评论/回答。

用户名/ uid对需要以两种格式存储。由于缺少一个更好的名字,我称之为 interlock

{
  "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子项时才能写入此内容。这将成为确定用户用户名的规范方式。
  3. 要验证用户名,请先查找/usernameInterlock/request/$username,然后查找$uid中获得的/usernameInterlock/confirm/$uid,如果该值与$ username匹配,则($username, $uid)是有效对。