【发布时间】:2015-03-20 04:35:15
【问题描述】:
是否可以使用 net/http 包和/或任何 gorilla 库在进入处理程序之前在每个 URL 上执行一些代码?例如,检查连接是否来自列入黑名单的 IP 地址?
【问题讨论】:
-
你想要的在这种情况下称为中间件,另见alexedwards.net/blog/making-and-using-middleware
是否可以使用 net/http 包和/或任何 gorilla 库在进入处理程序之前在每个 URL 上执行一些代码?例如,检查连接是否来自列入黑名单的 IP 地址?
【问题讨论】:
如果你想使用默认的 muxer,我觉得这很常见,你可以像这样创建中间件:
func mustBeLoggedIn(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
// Am i logged in?
if ...not logged in... {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
// Pass through to the original handler.
handler(w, r)
}
}
像这样使用它:
http.HandleFunc("/some/priveliged/action", mustBeLoggedIn(myVanillaHandler))
http.ListenAndServe(":80", nil)
【讨论】:
创建一个处理程序,在检查 IP 地址后调用另一个处理程序:
type checker struct {
h http.Handler
}
func (c checker) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if blackListed(r.RemoteAddr) {
http.Error(w, "not authorized", http.StatusForbidden)
return
}
c.h.ServeHTTP(w, r)
}
将此处理程序传递给 ListenAndServe,而不是您的原始处理程序。例如,如果您有:
err := http.ListenAndServe(addr, mux)
把代码改成
err := http.ListenAndServe(addr, checker{mux})
这也适用于 ListenAndServe 的所有变体。它适用于 http.ServeMux、Gorilla mux 和其他路由器。
【讨论】: