// 获取IP地址func GetIP(r *http.Request) string { remoteIP := r.RemoteAddr // 处理 X-Real-IP 头 if ip := r.Header.Get("X-Real-IP"); ip != "" { remoteIP = ip } // 处理 X-Forwarded-For 头,如果有多个IP,取第一个 if ips := r.Header.Get("X-Forwarded-For"); ips != "" { if ip := strings.TrimSpace(strings.Split(ips, ",")[0]); ip != "" { remoteIP = ip } } // 如果 remoteIP 是一个本地地址,则返回第一个 non-local IP if IsLocalhost(remoteIP) { ips := GetNonLocalIPs(r) if len(ips) > 0 { remoteIP = ips[0] } } return remoteIP}// 判断一个 IP 是否为本地地址func IsLocalhost(ip string) bool { ip = strings.TrimSpace(ip) return ip == "127.0.0.1" || ip == "::1" || strings.HasPrefix(ip, "192.168.") || strings.HasPrefix(ip, "10.") || strings.HasPrefix(ip, "172.16.")}// 获取 request 中非本地地址的 IP 列表func GetNonLocalIPs(r *http.Request) []string { ips := []string{} forwardedFors := r.Header.Get("X-Forwarded-For") if forwardedFors != "" { for _, forwardedFor := range strings.Split(forwardedFors, ",") { ip := strings.TrimSpace(forwardedFor) if !IsLocalhost(ip) { ips = append(ips, ip) } } } if len(ips) == 0 { // 获取 RemoteAddr 的 non-local IP ip, _, err := net.SplitHostPort(r.RemoteAddr) if err == nil && !IsLocalhost(ip) { ips = append(ips, ip) } } return ips}