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

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

问题描述

我正在使用 Firebase 开发一个在内部使用 Cloud Functions 作为 REST API 的应用.我的问题是,有没有一种简单的方法来实现类似于 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 repo.
  3. 将用户 UID 已调用该函数的事实推送到数据库,可能会将其添加到列表中.例如.admin.database().ref(`/userCalls/$uid`).push(ServerValue.TIMESTAMP).
  4. 使用 admin.database().ref(`/userCalls/$uid`).orderByKey().startAt(Date.now()-60000) 之类的方式查询最近调用的次数.
  5. 计算结果,如果太高则拒绝.

我不确定调用方的 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天全站免登陆