|
- package utils
-
- import (
- "net"
- "net/http"
- "strings"
- )
-
- func GetClientIP(r *http.Request) string {
- // 检查反向代理设置的常用头信息(按优先级排序)
- headers := []string{
- "X-Forwarded-For",
- "X-Real-Ip",
- "Proxy-Client-IP",
- "WL-Proxy-Client-IP",
- "HTTP_CLIENT_IP",
- "HTTP_X_FORWARDED_FOR",
- }
-
- for _, header := range headers {
- ip := r.Header.Get(header)
- if ip != "" {
- // 处理多IP情况(取第一个有效IP)
- parts := strings.Split(ip, ",")
- for _, part := range parts {
- ip = strings.TrimSpace(part)
- if ip != "" && !strings.EqualFold(ip, "unknown") {
- return parseIP(ip)
- }
- }
- }
- }
-
- // 回退到直接连接IP(带端口时需要处理)
- ip, _, err := net.SplitHostPort(r.RemoteAddr)
- if err != nil {
- return r.RemoteAddr // 无端口的情况直接返回
- }
- return parseIP(ip)
- }
-
- // 处理特殊格式IP(如IPv6本地地址)
- func parseIP(ip string) string {
- if ip == "::1" {
- return "127.0.0.1"
- }
- return ip
- }
|