1. // 获取IP地址
    2. func GetIP(r *http.Request) string {
    3. remoteIP := r.RemoteAddr
    4. // 处理 X-Real-IP 头
    5. if ip := r.Header.Get("X-Real-IP"); ip != "" {
    6. remoteIP = ip
    7. }
    8. // 处理 X-Forwarded-For 头,如果有多个IP,取第一个
    9. if ips := r.Header.Get("X-Forwarded-For"); ips != "" {
    10. if ip := strings.TrimSpace(strings.Split(ips, ",")[0]); ip != "" {
    11. remoteIP = ip
    12. }
    13. }
    14. // 如果 remoteIP 是一个本地地址,则返回第一个 non-local IP
    15. if IsLocalhost(remoteIP) {
    16. ips := GetNonLocalIPs(r)
    17. if len(ips) > 0 {
    18. remoteIP = ips[0]
    19. }
    20. }
    21. return remoteIP
    22. }
    23. // 判断一个 IP 是否为本地地址
    24. func IsLocalhost(ip string) bool {
    25. ip = strings.TrimSpace(ip)
    26. return ip == "127.0.0.1" || ip == "::1" || strings.HasPrefix(ip, "192.168.") || strings.HasPrefix(ip, "10.") || strings.HasPrefix(ip, "172.16.")
    27. }
    28. // 获取 request 中非本地地址的 IP 列表
    29. func GetNonLocalIPs(r *http.Request) []string {
    30. ips := []string{}
    31. forwardedFors := r.Header.Get("X-Forwarded-For")
    32. if forwardedFors != "" {
    33. for _, forwardedFor := range strings.Split(forwardedFors, ",") {
    34. ip := strings.TrimSpace(forwardedFor)
    35. if !IsLocalhost(ip) {
    36. ips = append(ips, ip)
    37. }
    38. }
    39. }
    40. if len(ips) == 0 {
    41. // 获取 RemoteAddr 的 non-local IP
    42. ip, _, err := net.SplitHostPort(r.RemoteAddr)
    43. if err == nil && !IsLocalhost(ip) {
    44. ips = append(ips, ip)
    45. }
    46. }
    47. return ips
    48. }