package middleware import ( "errors" "net" "net/http" "strings" ) // GetRealIP 提取客户端真实 IP 地址 func GetRealIP(r *http.Request) string { headers := []string{"x-forwarded-for", "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "X-Real-IP"} // 遍历头信息,找到第一个有效 IP for _, header := range headers { ip := extractIP(r.Header.Get(header)) if ip != "" { return ip } } // 获取 RemoteAddr,如果经过代理则是代理 IP ip, _, err := net.SplitHostPort(r.RemoteAddr) if err == nil && ip != "" { return ip } // 检查是否是本地地址 if strings.HasPrefix(ip, "127.0.0.1") || strings.HasPrefix(ip, "[::1]") { if externalIP, err := getExternalIP(); err == nil { return externalIP.String() } } return "" } // 提取 IP 地址并返回第一个非空部分 func extractIP(ips string) string { if ips == "" || strings.EqualFold(ips, "unknown") { return "" } // 返回第一个有效 IP return strings.TrimSpace(strings.Split(ips, ",")[0]) } // 获取非 127.0.0.1 的局域网 IP func getExternalIP() (net.IP, error) { ifaces, err := net.Interfaces() if err != nil { return nil, err } for _, iface := range ifaces { if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 { continue } addrs, err := iface.Addrs() if err != nil { return nil, err } for _, addr := range addrs { ip := getIPFromAddr(addr) if ip != nil { return ip, nil } } } return nil, errors.New("not connected to the network") } func getIPFromAddr(addr net.Addr) net.IP { var ip net.IP switch v := addr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP } if ip != nil && !ip.IsLoopback() { return ip.To4() } return nil }