FB-rate limiting (Sicherheits-Regeln?
Startete ich meine erste open repository Projekt, EphChat, und Menschen machte sich sofort auf die überschwemmung mit Anfragen.
Macht FB einen Weg zu den limit-Anforderungen in der Sicherheits-Regeln? Ich nehme an, es gibt einen Weg, es zu tun mit dem Zeitpunkt der Anforderung und dem Zeitpunkt der zuvor geschriebenen Daten, kann aber nicht finden, nichts in der Dokumentation darüber, wie würde ich dies tun.
Den aktuellen Sicherheits-Regeln sind wie folgt.
{
"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
}
}
}
}
}
Ich würde wollen, rate-limit, schreibt (und liest?) zu den db für die gesamte Zimmer-Objekt, also nur 1 Anfrage pro Sekunde (zum Beispiel).
Dank!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den trick zu halten, ist eine Prüfung der letzten Zeit ein Benutzer eine Nachricht gepostet. Dann können Sie erzwingen, die Zeit, jede Nachricht gepostet wird, auf der Grundlage der audit-Wert:
Ihn in Aktion zu sehen in diesem fiddle. Hier ist der Kern von dem, was in der Geige:
$user
in der ersten Tabelle. Nicht sicher, ob die aktuelle Implementierung unterstützt, aber Sie können auch zu begrenzen, nachsenden, und vielleicht setzen Sie beide a und min Zeitfenster für jede dieser Nachrichten. Klingt das richtig für Sie? Ich denke, das problem ist jedoch, dass Sie könnten Klumpen Nachrichten zusammen zu bekommen Vergangenheit die limitierenden Faktoren...newData.val() === now
funktioniert wohl in diesen Tagen (nicht vor 2 Jahren, wenn dies gebucht wurde)next()
- Funktion funktioniert?Habe ich nicht genug Bewertungen schreiben Sie in den Kommentar, aber ich Stimme Victor ' s Kommentar. Wenn Sie das
fb.child('messages').push(...)
in einer Schleife (d.h.for (let i = 0; i < 100; i++) {...}
) dann wäre es erfolgreich schieben 60-80 meessages ( in 500ms-Fenster-Rahmen.Inspiriert von Kato Lösung, ich schlage vor, eine änderung der Regeln wie folgt:
Den .js-code ist sehr ähnlich zu Kato ' s Lösung, außer dass die getTimestamp zurückkehren würde, {time: number, key: string} für den nächsten Rückruf. Dann hätten wir nur
ref.update({[key]: data})
Diese Lösung vermeidet die 500ms Zeit-Fenster, wir brauchen uns nicht zu sorgen, dass der client muss schnell genug sein, um die push-Nachricht innerhalb von 500ms. Wenn mehrere schreiben, Anfragen (spamming), Sie kann nur das schreiben in 1 einzelner Schlüssel in der
messages
. Optional erstellen-einzige Regel inmessages
verhindert, dass aus geschieht.Den vorhandenen Antworten verwenden Sie zwei Datenbank-updates: (1) markieren Sie ein timestamp, und (2) befestigen Sie die markierten timestamp in das tatsächliche schreiben. Kato Antwort erfordert 500ms Zeit-Fenster, während ChiNhan ist, erfordert die Erinnerung an die nächsten Schlüssel.
Es ist ein einfacher Weg, es zu tun in einer einzigen Datenbank-update. Die Idee ist zu schreiben mehrerer Werte in die Datenbank, wenn Sie mit der update() Methode. Die Sicherheits-Regeln überprüft die geschriebenen Werte so, dass das schreiben nicht mehr als die Quote. Die Quote ist definiert als ein paar Werte: quotaTimestamp und postCount. Der postCount ist die Anzahl der posts innerhalb von 1 minute von der quotaTimestamp. Die security-Regeln einfach ablehnt, den nächsten zu schreiben, wenn der postCount einen bestimmten Wert übersteigt. Der postCount wird zurückgesetzt, wenn die quotaTimestamp ist staler als 1 minute.
Hier ist, wie um eine neue Nachricht zu schreiben:
Der Sicherheitsregeln zu bewerten, zu begrenzen auf höchstens 5 posts pro minute:
Hinweis: die serverTimeOffset sollte beibehalten werden, um zu vermeiden, clock-skew.