gpt4 book ai didi

http - 限制 HTTP 请求的速率(通过 http.HandlerFunc 中间件)

转载 作者:IT老高 更新时间:2023-10-28 13:07:00 26 4
gpt4 key购买 nike

我正在寻找编写一小块限速中间件:

  1. 允许我为每个远程 IP 设置合理的速率(例如 10 个请求/秒)
  2. 可能(但不是必须)允许爆发
  3. 丢弃(关闭?)超出速率的连接并返回 HTTP 429

然后我可以将它包裹在身份验证路由或其他可能容易受到暴力攻击的路由(即使用过期 token 的密码重置 URL 等)周围。有人暴力破解 16 或 24 字节 token 的可能性非常低,但多走一步也无妨。

我看过 https://code.google.com/p/go-wiki/wiki/RateLimiting但我不确定如何将它与 http.Request(s) 协调起来。此外,我不确定我们如何在任何时间段内“跟踪”来自给定 IP 的请求。

理想情况下我会得到这样的结果,注意我在反向代理 (nginx) 后面,所以我们正在检查 REMOTE_ADDR HTTP header 而不是使用 r .RemoteAddr:

// Rate-limiting middleware
func rateLimit(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {

remoteIP := r.Header.Get("REMOTE_ADDR")
for req := range (what here?) {
// what here?
// w.WriteHeader(429) and close the request if it exceeds the limit
// else pass to the next handler in the chain
h.ServeHTTP(w, r)
}
}

// Example routes
r.HandleFunc("/login", use(loginForm, rateLimit, csrf)
r.HandleFunc("/form", use(editHandler, rateLimit, csrf)

// Middleware wrapper, for context
func use(h http.HandlerFunc, middleware ...func(http.HandlerFunc) http.HandlerFunc) http.HandlerFunc {
for _, m := range middleware {
h = m(h)
}

return h
}

我很感激这里的一些指导。

最佳答案

您链接到的速率限制示例是一个通用示例。它使用范围是因为它通过 channel 获取请求。

HTTP 请求是另一回事,但这里并没有什么复杂的地方。请注意,您不会遍历请求 channel 或任何东西 - 您的 HandlerFunc 会为每个传入请求单独调用。

func rateLimit(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
remoteIP := r.Header.Get("REMOTE_ADDR")
if exceededTheLimit(remoteIP) {
w.WriteHeader(429)
// it then returns, not passing the request down the chain
} else {
h.ServeHTTP(w, r);
}
}
}

现在,选择存储速率限制计数器的位置由您决定。一种解决方案是简单地使用将 IP 映射到其请求计数器的全局映射(不要忘记安全的并发访问)。但是,您必须知道请求是在多长时间之前提出的。

Sergio 建议使用 Redis。它的键值特性非常适合像这样的简单结构,并且您可以免费获得到期。

关于http - 限制 HTTP 请求的速率(通过 http.HandlerFunc 中间件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20298220/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com