我花了最后一个小时试图寻找一种解决方案来限制我的api。
例如,我想限制路径loss = tf.math.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(one_hot_labels, logits))
。但是大多数速率限制对每个人都具有1个速率限制。我想使用可由用户生成的api密钥。人们每天可以生成免费的api,比如说1000个请求。然后,如果他们支付一些钱,则每天可以收到5000个请求。
我想将这些api密钥存储在mysql数据库中。
有人对此有任何解决方案吗?
答案 0 :(得分:1)
构建项目的一种方法是:
user_keys表,包括到目前为止的api密钥,用户,创建时间和使用次数。 当用户尝试生成密钥时,请检查它是否还不存在,然后将其添加到数据库中。
请求到达时,检查密钥是否存在,如果存在,请执行以下操作:
1:如果自创建日期起已过24小时,则将使用次数设置为0 2:增加使用次数
如果找到了API密钥,并且密钥密钥已达到1k,则表明用户已达到限制。
这是一个基本实现,效率不是很高,您需要将API密钥缓存在内存中,或者仅在nodejs中的哈希图中,或者使用memcached / redis。但是,请先使其运行,然后再尝试对其进行优化。
编辑:一些代码示例
//overly simple in memory cache
const apiKeys = {}
//one day's worth in milliseconds, used later on
const oneDayTime = 1000 * 60 * 60 * 24
//function to generate new API keys
function generateKey(user) {
if (apiKeys[user]) {
throw Error("user already has a key")
}
let key = makeRandomHash(); // just some function that creates a random string like "H#4/&DA23#$X/"
//share object so it can be reached by either key or user
//terrible idea, but when you save this in mysql you can just do a normal search query
apiKeys[user] = {
key: key,
user: user,
checked: Date.Now(),
uses: 0
}
apiKeys[key] = apiKeys[user]
}
// a function that does all the key verification for us
function isValid(key) {
//check if key even exists first
if (!apiKeys[key]) throw Error("invalid key")
//if it's been a whole day since it was last checked, reset its uses
if (Date.now() - apiKeys[key].checked >= oneDayTime) {
apiKeys[key].uses = 0
apiKeys[key].checked = Date.now()
}
//check if the user limit cap is reached
if (apiKeys[key].uses >= 1000) throw error("User daily qouta reached");
//increment the user's count and exit the function without errors
apiKeys[key].uses++;
}
//express middleware function
function limiter(req, res, next) {
try {
// get the API key, can be anywhere, part of json or in the header or even get query
let key = req.body["api_key"]
// if key is not valid, it will error out
isValid(key)
// pass on to the next function if there were no errors
next()
} catch (e) {
req.send(e)
}
}
这是一个较简单的想法的过度简化的实现,但我希望它能使想法得到理解。
您要在此处更改的主要内容是如何保存和检索API密钥