如何避免 firebase 安全警告并在注册时验证用户名?
How to avoid firebase security warning and validate username while signup?
我正在使用 firebase 数据库作为我的存储。注册时我会存储用户名以验证用户名的唯一性。我声明 firebase 安全规则如下,
{
"rules": {
".read": true,
".write": true
}
}
我的数据库结构如下,
Users
o**kcarw***27p**enV**UcB3***
Email: "testing@mail.com"
UserName: "GokulNew"
但是,如果我按上述方式声明,则会收到一个 firebase 警告,因为“您的项目的实时数据库“项目”具有不安全的规则”。
所以后来我改变了安全规则如下,
{
"rules": {
".read": "auth !=null",
".write": "auth !=null"
}
}
如果我按上述方式声明,则不会显示安全警告,但由于安全规则不允许我注册。所以我再次更改规则如下,
{
"rules": {
".read": "auth !=null",
".write": "auth !=null",
"Users":{
".read": true,
".write": true
}
}
}
在此之后,允许我注册,但显示安全警告。如何避免安全警告,同时我需要在注册时验证用户名。
下面是 Java 注册码
Query usernameQuery = FirebaseDatabase.getInstance().getReference().child("Users").
orderByChild("UserName").equalTo(upperCaseChar(username));
usernameQuery.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
if (snapshot.getChildrenCount() > 0) {
usernameLayout.setError("Username is already taken");
vibrator.vibrate(VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE));
dialog.dismiss();
Toast.makeText(RegisterActivity.this, "Username is already taken, Choose new one", Toast.LENGTH_SHORT).show();
} else {
//sign-up and storing the data to firebase
}
}
}
希望我的要求清楚,提前致谢,
您的规则应遵循 principle of least privilege, meaning they allow exactly what your code needs and nothing more. Since the code you shared performs a query on /Users
, you want to secure for that query,看起来像这样:
...
"Users": {
".read": "query.orderByChild == 'UserName' &&
query.equalTo.length > 0"
}
...
这只允许(如果有效,因为我没有测试长度检查)在 /Users
上读取在 UserNames
上查询并指定一个 equalTo
值,以便与您的代码匹配。
尽管如此,我还是建议为此考虑另一种数据结构,因为当多个用户大约同时尝试使用相同的名称时,您当前的代码可能无法正常工作。为了让它工作,你应该引入一个 top-level 节点,你在其中使用用户名作为键,然后使用事务写入那里,并在 security rules ensure a value can only be written if non exists yet.
有关这方面的更多信息,另请参阅之前的这些 questions about unique usernames。
我正在使用 firebase 数据库作为我的存储。注册时我会存储用户名以验证用户名的唯一性。我声明 firebase 安全规则如下,
{
"rules": {
".read": true,
".write": true
}
}
我的数据库结构如下,
Users
o**kcarw***27p**enV**UcB3***
Email: "testing@mail.com"
UserName: "GokulNew"
但是,如果我按上述方式声明,则会收到一个 firebase 警告,因为“您的项目的实时数据库“项目”具有不安全的规则”。 所以后来我改变了安全规则如下,
{
"rules": {
".read": "auth !=null",
".write": "auth !=null"
}
}
如果我按上述方式声明,则不会显示安全警告,但由于安全规则不允许我注册。所以我再次更改规则如下,
{
"rules": {
".read": "auth !=null",
".write": "auth !=null",
"Users":{
".read": true,
".write": true
}
}
}
在此之后,允许我注册,但显示安全警告。如何避免安全警告,同时我需要在注册时验证用户名。 下面是 Java 注册码
Query usernameQuery = FirebaseDatabase.getInstance().getReference().child("Users").
orderByChild("UserName").equalTo(upperCaseChar(username));
usernameQuery.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
if (snapshot.getChildrenCount() > 0) {
usernameLayout.setError("Username is already taken");
vibrator.vibrate(VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE));
dialog.dismiss();
Toast.makeText(RegisterActivity.this, "Username is already taken, Choose new one", Toast.LENGTH_SHORT).show();
} else {
//sign-up and storing the data to firebase
}
}
}
希望我的要求清楚,提前致谢,
您的规则应遵循 principle of least privilege, meaning they allow exactly what your code needs and nothing more. Since the code you shared performs a query on /Users
, you want to secure for that query,看起来像这样:
...
"Users": {
".read": "query.orderByChild == 'UserName' &&
query.equalTo.length > 0"
}
...
这只允许(如果有效,因为我没有测试长度检查)在 /Users
上读取在 UserNames
上查询并指定一个 equalTo
值,以便与您的代码匹配。
尽管如此,我还是建议为此考虑另一种数据结构,因为当多个用户大约同时尝试使用相同的名称时,您当前的代码可能无法正常工作。为了让它工作,你应该引入一个 top-level 节点,你在其中使用用户名作为键,然后使用事务写入那里,并在 security rules ensure a value can only be written if non exists yet.
有关这方面的更多信息,另请参阅之前的这些 questions about unique usernames。