你需要做兩件事情:一個是中間件處理程序前處理您的要求和驗證IP包的多路複用器。另一個是獲取用戶的真實IP,如果您位於防火牆或負載平衡器的後面(導致地址始終是LB的地址),或者您的用戶位於代理之後,這非常重要。
至於包裹你的多路複用器,這是很簡單的:
apiServer := &http.Server{
Addr: "0.0.0.0:8080",
Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// get the real IP of the user, see below
addr := getRealAddr(req)
// the actual vaildation - replace with whatever you want
if (addr != "1.2.3.4") {
http.Error(w, "Blocked", 401)
return
}
// pass the request to the mux
apiMux.ServeHTTP(w,req)
}),
}
而且我安裝了getRealAddr
功能,是在我做了這樣的一個實際的項目:
func getRealAddr(r *http.Request) string {
remoteIP := ""
// the default is the originating ip. but we try to find better options because this is almost
// never the right IP
if parts := strings.Split(r.RemoteAddr, ":"); len(parts) == 2 {
remoteIP = parts[0]
}
// If we have a forwarded-for header, take the address from there
if xff := strings.Trim(r.Header.Get("X-Forwarded-For"), ","); len(xff) > 0 {
addrs := strings.Split(xff, ",")
lastFwd := addrs[len(addrs)-1]
if ip := net.ParseIP(lastFwd); ip != nil {
remoteIP = ip.String()
}
// parse X-Real-Ip header
} else if xri := r.Header.Get("X-Real-Ip"); len(xri) > 0 {
if ip := net.ParseIP(xri); ip != nil {
remoteIP = ip.String()
}
}
return remoteIP
}
至於過濾,它可以基於一組ips或CIDR範圍,當然這取決於你。
如果你感興趣的話,上面的代碼是從API工具包構建我寫的並用所謂的頂點,它有這個建於:https://github.com/EverythingMe/vertex
的可能的複製[如何限制HTTP服務器的連接數實現在去?](http://stackoverflow.com/questions/22625367/how-to-limit-the-connection-count-of-an-http-server-implemented-in-go) – Tinwor
@Tinwor不是真的重複的那 –
類似的問題:http://stackoverflow.com/questions/28070923/golang-net-http-and-gorilla-run-code-before-handler –