第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Firebase速率限制在安全規(guī)則中?

Firebase速率限制在安全規(guī)則中?

開滿天機 2019-10-28 18:34:25
我啟動了我的第一個開放式存儲庫項目EphChat,人們迅速開始向其發(fā)送大量請求。Firebase是否可以對安全規(guī)則中的限制請求進行評級?我假設有一種方法可以使用請求時間和先前寫入的數(shù)據(jù)時間,但是在文檔中找不到我該如何做的任何事情。當前的安全規(guī)則如下。{    "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          }        }      }    }}我想對整個Rooms對象的數(shù)據(jù)庫的寫入(和讀???)進行速率限制,因此每秒只能發(fā)出1個請求(例如)。謝謝!
查看完整描述

3 回答

?
長風秋雁

TA貢獻1757條經(jīng)驗 獲得超7個贊

訣竅是對用戶上次發(fā)布消息的時間進行審核。然后,您可以根據(jù)審核值來強制發(fā)布每條消息的時間:


{

  "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 

          }

        }

      } 

  }

}

在這個小提琴中看到它的實際效果。這是小提琴演奏的要點:


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);

            }

        });

    })

}


查看完整回答
反對 回復 2019-10-28
?
largeQ

TA貢獻2039條經(jīng)驗 獲得超8個贊

現(xiàn)有答案使用兩個數(shù)據(jù)庫更新:(1)標記時間戳,以及(2)將標記的時間戳附加到實際寫入。Kato的答案需要500毫秒的時間窗口,而ChiNhan的答案則需要記住下一個鍵。


在單個數(shù)據(jù)庫更新中,有一種更簡單的方法來執(zhí)行此操作。這個想法是使用update()方法一次將多個值寫入數(shù)據(jù)庫。安全規(guī)則將驗證寫入的值,以使寫入不超過配額。配額被定義為一對值:quotaTimestamp和postCount。postCount是在quotaTimestamp的1分鐘內(nèi)寫入的帖子數(shù)。如果postCount超過某個值,則安全規(guī)則僅拒絕下一次寫入。當quotaTimestamp超過1分鐘時,將重置postCount。


這是發(fā)布新消息的方法:


function postMessage(user, message) {

  const now = Date.now() + serverTimeOffset;

  if (!user.quotaTimestamp || user.quotaTimestamp + 60 * 1000 < now) {

    // Resets the quota when 1 minute has elapsed since the quotaTimestamp.

    user.quotaTimestamp = database.ServerValue.TIMESTAMP;

    user.postCount = 0;

  }

  user.postCount++;


  const values = {};

  const messageId = // generate unique id

  values[`users/${user.uid}/quotaTimestamp`] = user.quotaTimestamp;

  values[`users/${user.uid}/postCount`] = user.postCount;

  values[`messages/${messageId}`] = {

    sender: ...,

    message: ...,

    ...

  };

  return this.db.database.ref().update(values);

}

安全規(guī)則將速率限制為每分鐘最多5個帖子:


{

  "rules": {

    "users": {

      "$uid": {

        ".read": "$uid === auth.uid",

        ".write": "$uid === auth.uid && newData.child('postCount').val() <= 5",

        "quotaTimestamp": {

          // Only allow updating quotaTimestamp if it's staler than 1 minute.

          ".validate": "

            newData.isNumber()

            && (newData.val() === now

              ? (data.val() + 60 * 1000 < now)

              : (data.val() == newData.val()))"

        },

        "postCount": {

          // Only allow postCount to be incremented by 1

          // or reset to 1 when the quotaTimestamp is being refreshed.

          ".validate": "

            newData.isNumber()

            && (data.exists()

              ? (data.val() + 1 === newData.val()

                || (newData.val() === 1

                    && newData.parent().child('quotaTimestamp').val() === now))

              : (newData.val() === 1))"

        },

        "$other": { ".validate": false }

      }

    },


    "messages": {

      ...

    }

  }

}

注意:應保持serverTimeOffset以避免時鐘偏斜。

查看完整回答
反對 回復 2019-10-28
  • 3 回答
  • 0 關注
  • 577 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號