我写了一个非常简单的轮询脚本,可以将投票保存到Firebase数据库。为了防止同一个用户多次投票,我将电子邮件保存到一个单独的对象,然后在可以放置新条目之前检查它(这是我自己的信息,不需要高安全性)。
到目前为止它似乎确实阻止了基本的犯规,但是我得到了很多快速连续多次投票的实例(可能比浏览器重新加载的速度快)。在最糟糕的情况下,有16票相差毫秒。
有没有办法阻止这些快速连续写入Firebase或JavaScript端?
Firebase数据:
{
"votes" : {
" obj1 " : {
"-KHXPWtcxzXhs2ULBE1Q" : {
"name" : " name1 ",
"email" : "email1",
"timestamp" : 1463013744297
},
"-KHXPWuyhTg6S3Qcw4e9" : {
"name" : " name1 ",
"email" : "email1",
"timestamp" : 1463013744382
}
},
"obj2" : {
"-KHZ20CRiT5fs6H4Nhel" : {
"name" : "name2",
"email" : "email2",
"timestamp" : 1463041135613
}
},
},
"email" : {
"-KHXPWtHSNYWBmvXsmNx" : {
"email" : "email1",
"timestamp" : 1463013744292
},
"-KHXPWus4hSwi1t00Gq_" : {
"email" : "email1",
"timestamp" : 1463013744377
},
"-KHZ20CdfcsoGjvn98Q" : {
"email" : "email2",
"timestamp" : 1463041135606
},
}
}
jQuery:
var validateEmail = /^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,4}$/i;
function castVote() {
var ref = new Firebase('firebaseurl');
$( ".notification.exists" ).hide();
$( ".notification.valid" ).hide();
var obj = $('#obj').val().toLowerCase();
var email = $('#email').val().toLowerCase();
var emailref = ref.child("email");
if (validateEmail.test(email)){
emailref.once('value', function(snapshot) {
var exists = false;
snapshot.forEach(function(childSnapshot){
if(email === childSnapshot.val().email){
exists = true;
}
})
if (exists){
$( ".notification.exists" ).show();
}
else{
write(obj,email,ref,emailref);
}
});
}
else{
$( ".notification.valid" ).show();
}
}
function write(obj,email,ref,emailref){
var objref = ref.child("obj/" + obj);
//save email
emailref.push().set({
email:email,
"timestamp": Firebase.ServerValue.TIMESTAMP
});
//save vote
objref.push().set({
obj: obj,
"email": email,
"timestamp": Firebase.ServerValue.TIMESTAMP
});
//clear fields
$('#obj').val('');
$('#email').val('');
}
}
答案 0 :(得分:5)
您应该使用安全规则在Firebase端阻止此操作。阻止用户重新投票的简单规则可以是 -
请注意,您需要将此代码段放在安全规则中的正确位置 -
"votes" : {
// keep .read/.write as applicable
"$obj" : {
"$user" : {
// keep .read/.write as applicable
// Don't allow write if the parent obj already contains this user entry
".validate" : "!data.parent().hasChild($user)"
}
}
}
这样,一旦您为某个votes
将用户的投票插入obj
,另一次插入就会失败。