3

我正在研究如何完成速率限制,似乎很多 API(包括 StackOverflow v1 API)通过 IP 限制速率或将 API 密钥限制为在某个域上使用。这是如何可靠地完成的?

当我查看一个由 XHR 向我的 API 生成的请求时,它有一个引用者(通常)和一个远程地址。我认为远程地址很有希望,但看起来那是使用该网站的用户的地址,而不是发出请求的网站的地址。推荐人看起来并不总是发送,但我想当它在那里时,可以查找与服务器对应的IP。

我的观点是:这一定是可能的,因为一些大牌做到了;他们是怎么做到的呢?

4

2 回答 2

3

在欺诈领域,这些被称为速度控制,而在流量管理中,它类似于“流量整形”。基本上,您允许每个时间段的有限使用,例如,您可能只允许 10 个请求/分钟/IP 地址。

对于每个“请求”,确定远程地址(C 中的 getpeername()),此函数将始终是远程用户的 IP 地址。然后简单地计算每个时间段如何处理请求,如果超出限制,请执行任何操作。在伪代码中

Get block for remote ip
If time-now is new window, then reset usage to zero
Add one to usage count
If usage > allowance then .....
Else if usage > allowance*0.75 then slow-down 
Else ok

虽然我展示了一个周期,但大多数实现通常是多个周期的平均值,例如每分钟一小时等。它们也倾向于允许突发并且只限制持续负载,但这取决于您希望允许的配置文件。

如果这是针对 API 的,那么简单地减慢请求而不是提供硬错误是正常的。不能保证另一端的客户端会处理该错误。如果是用户屏幕,则可以显示超出限制。

您当然可以通过任何您希望的维度进行限制,IP 地址、引用、浏览器类型!、pageurl、cookie。如果您使用 getpeername,请注意,如果多个并发用户位于公共专用路由器后面,则他们都可以拥有相同的远程 IP 地址。

于 2013-03-18T03:41:10.067 回答
1

您可以使用请求的远程地址或 x-forwarded-for 标头中的第一个 ip。

仅当您的应用程序位于您信任的反向代理之后或您在 PaaS 上运行时,您才使用标头。您需要控制您信任的级别。检查 nginx 模块 real-ip。

使用 ip 地址是匿名流量的一种非常常见的模式,因为此时您对用户一无所知。一旦用户通过身份验证(作为人或应用程序),最好使用其 id 而不是 ip。

于 2015-04-19T14:33:27.807 回答