Google/Firebase云功能的速率限制? [英] Rate limiting for Google/Firebase cloud functions?

查看:93
本文介绍了Google/Firebase云功能的速率限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Firebase开发内部使用Cloud Functions作为REST API的应用程序.我的问题是,是否有一种简单的方法来实现按IP/按用户的速率限制,类似于 slack使用,但以每个IP 每个用户为基础,而不是每个应用(因为全部)一个应用程序).最好还提供对小脉冲的可选支持.

I am using Firebase to develop an app that uses Cloud Functions as a REST API internally. My question is, is there an easy way to implement per-IP/per-user rate-limiting similar to what slack uses, except on a per-IP and per-user basis, rather than per-app (since it's all one app). Optional support for small bursts is preferable as well.

示例代码(请参见// TODO:注释):

Example code (see the // TODO: comments):

exports.myCoolFunction = functions.https.onRequest((req, res) => {
        // TODO: implement IP rate-limiting here
        unpackToken(req).then((token) => { // unpackToken resolves with a response similar to verifyIdToken based on the "Authorization" header contents
                // TODO: implement user-based rate-limiting here (based on token.uid)
                if (!req.body) return res.status(400).end();
                if (typeof req.body.name !== "string") return res.status(400).end();
                if (typeof req.body.user !== "string") return res.status(400).end();

                // more input sanitization and function logic here

                return res.status(501).end(); // fallback in all requests, do not remove
        }).catch(() => res.status(403).end());
});

如果超出速率限制,我想简单地使用529 Too Many Requests状态代码来终止请求.这是为了防止应用程序错误泛滥到网络中,并防止滥用REST API.

I want to terminate the request simply with a 529 Too Many Requests status code if the rate limit is exceeded. This is to prevent application errors from flooding the network and to prevent abuse of the REST API.

这应该考虑到Firebase向上/向下旋转服务器实例并同时运行多个实例.

This should take into account Firebase spinning up/down server instances and having multiple instances running simultaneously.

我还在使用Firestore数据库,并在必要时可以使用旧版实时数据库.

I am also using a Firestore database and can use the legacy real-time database if necessary.

推荐答案

按用户进行操作听起来很简单:

Doing this on a per-user basis sounds fairly straightforward:

  1. 每个请求将用户的ID令牌传递给Cloud Functions.
  2. 在您的Cloud Function中解码ID令牌以确定UID.有关前两个步骤的示例,请参见 functions-samples存储库.
  3. 将用户UID调用该函数到数据库的事实(可能将其添加到列表中).例如. admin.database().ref(`/userCalls/$uid`).push(ServerValue.TIMESTAMP).
  4. 使用诸如admin.database().ref(`/userCalls/$uid`).orderByKey().startAt(Date.now()-60000)之类的字词查询最近的通话次数.
  5. 计算结果,如果结果过高则拒绝.
  1. Pass the ID token of the user to Cloud Functions with each request.
  2. Decode the ID token in your Cloud Function to determine the UID. For an example of these first two steps, see the functions-samples repo.
  3. Push the fact that user UID has called the function to a database, probably adding it to a list. E.g. admin.database().ref(`/userCalls/$uid`).push(ServerValue.TIMESTAMP).
  4. Query for the number of recent calls with something like admin.database().ref(`/userCalls/$uid`).orderByKey().startAt(Date.now()-60000).
  5. Count the results and reject if it is too high.

我不确定呼叫者的IP地址是否传递给Cloud Functions.如果是这样,则可以对IP地址执行相同的逻辑.如果未通过,则很难以不容易被欺骗的方式对限制进行评分.

I'm not sure if the IP address of the caller is passed to Cloud Functions. If it is, you can do the same logic for the IP address. If it isn't passed, it'll be hard to rate limit in a way that can't be easily spoofed.

这篇关于Google/Firebase云功能的速率限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆