我正在使用Firebase开发内部使用Cloud Functions作为REST API的应用程序。我的问题是,是否有一种简单的方法来实现类似于slack uses的每个IP/每个用户的速率限制,除了基于每个IP的每个用户的基础之外,而不是每个应用(因为它是所有一个应用)。可选的对小突发的支持也是可取的。
示例代码(请参见// TODO:注释):

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。

最佳答案

在每个用户的基础上这样做听起来很简单:

  • 随每个请求将用户的ID token 传递给Cloud Functions。
  • 解码您的Cloud Function中的ID token 以确定UID。有关前两个步骤的示例,请参见the functions-samples repo
  • 将用户UID调用此函数的事实推到数据库中,可能将其添加到列表中。例如。 admin.database().ref(`/userCalls/$uid`).push(ServerValue.TIMESTAMP)
  • 使用admin.database().ref(`/userCalls/$uid`).orderByKey().startAt(Date.now()-60000)之类的查询最近的调用数量。
  • 计算结果,如果结果过高则拒绝。

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

    关于node.js - Google/Firebase云功能的速率限制?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50741936/

    10-16 20:03