Bri*_*yer 30 rate-limiting firebase firebase-security firebase-realtime-database
我启动了我的第一个开放式存储库项目EphChat,人们立即开始充斥它的请求.
Firebase是否有办法对安全规则中的限制请求进行评级?我假设有一种方法可以使用请求的时间和先前写入的数据的时间,但在文档中找不到有关如何执行此操作的任何内容.
目前的安全规则如下.
{
"rules": {
"rooms": {
"$RoomId": {
"connections": {
".read": true,
".write": "auth.username == newData.child('FBUserId').val()"
},
"messages": {
"$any": {
".write": "!newData.exists() || root.child('rooms').child(newData.child('RoomId').val()).child('connections').hasChild(newData.child('FBUserId').val())",
".validate": "newData.hasChildren(['RoomId','FBUserId','userName','userId','message']) && newData.child('message').val().length >= 1",
".read": "root.child('rooms').child(data.child('RoomId').val()).child('connections').hasChild(data.child('FBUserId').val())"
}
},
"poll": {
".write": "auth.username == newData.child('FBUserId').val()",
".read": true
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想对整个Rooms对象的db进行速率限制写入(和读取?),因此每秒只能生成1个请求(例如).
谢谢!
Kat*_*ato 42
诀窍是对用户上次发布消息的时间进行审计.然后,您可以根据审计值强制发布每条消息的时间:
{
"rules": {
// this stores the last message I sent so I can throttle them by timestamp
"last_message": {
"$user": {
// timestamp can't be deleted or I could just recreate it to bypass our throttle
".write": "newData.exists() && auth.uid === $user",
// the new value must be at least 5000 milliseconds after the last (no more than one message every five seconds)
// the new value must be before now (it will be since `now` is when it reaches the server unless I try to cheat)
".validate": "newData.isNumber() && newData.val() === now && (!data.exists() || newData.val() > data.val()+5000)"
}
},
"messages": {
"$message_id": {
// message must have a timestamp attribute and a sender attribute
".write": "newData.hasChildren(['timestamp', 'sender', 'message'])",
"sender": {
".validate": "newData.val() === auth.uid"
},
"timestamp": {
// in order to write a message, I must first make an entry in timestamp_index
// additionally, that message must be within 500ms of now, which means I can't
// just re-use the same one over and over, thus, we've effectively required messages
// to be 5 seconds apart
".validate": "newData.val() >= now - 500 && newData.val() === data.parent().parent().parent().child('last_message/'+auth.uid).val()"
},
"message": {
".validate": "newData.isString() && newData.val().length < 500"
},
"$other": {
".validate": false
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这个小提琴中看到它的实际效果.以下是小提琴中的主要内容:
var fb = new Firebase(URL);
var userId; // log in and store user.uid here
// run our create routine
createRecord(data, function (recordId, timestamp) {
console.log('created record ' + recordId + ' at time ' + new Date(timestamp));
});
// updates the last_message/ path and returns the current timestamp
function getTimestamp(next) {
var ref = fb.child('last_message/' + userId);
ref.set(Firebase.ServerValue.TIMESTAMP, function (err) {
if (err) { console.error(err); }
else {
ref.once('value', function (snap) {
next(snap.val());
});
}
});
}
function createRecord(data, next) {
getTimestamp(function (timestamp) {
// add the new timestamp to the record data
var data = {
sender: userId,
timestamp: timestamp,
message: 'hello world'
};
var ref = fb.child('messages').push(data, function (err) {
if (err) { console.error(err); }
else {
next(ref.name(), timestamp);
}
});
})
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8546 次 |
最近记录: |