我正在寻找一小部分限速中间件:
然后,我可以围绕身份验证路由或其他可能容易遭受暴力攻击的路由(即使用过期的令牌密码重置URL等).有人粗暴地强制使用16或24字节令牌的可能性非常低,但是进行额外步骤并没有什么坏处.
我查看了https://code.google.com/p/go-wiki/wiki/RateLimiting,但我不确定如何将其与http.Request(s)进行协调.此外,我不确定在任何时间段内我们如何"跟踪"来自给定IP的请求.
理想情况下,我最终得到类似的东西,注意我是在反向代理(nginx)的后面,所以我们正在检查REMOTE_ADDRHTTP头而不是使用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
}
Run Code Online (Sandbox Code Playgroud)
我在这里感谢一些指导.
jus*_*nas 11
您链接的速率限制示例是一般的.它使用范围,因为它通过通道获取请求.
这是一个与HTTP请求不同的故事,但这里没有什么真正复杂的.请注意,您不会迭代请求或任何事件的通道 - 分别为每个传入请求调用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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,选择存储速率限制计数器的位置取决于您.一种解决方案是简单地使用将IP映射到其请求计数器的全局映射(不要忘记安全的并发访问).但是,您必须知道请求发生了多久以前.
Sergio建议使用Redis.它的键值特性非常适合这种简单的结构,并且您可以免费使用.
| 归档时间: |
|
| 查看次数: |
5635 次 |
| 最近记录: |