package tools import ( "net" "net/http" "strings" ) // ClientIP 首先读取 X-Forwarded-For header 中用 , 分隔的第一个ip地址, // 如果这个地址不存在,就会从 X-Real-Ip header 中获取,如果还是不存在, // 说明流量并非是由反向代理转发而来,而是客户端直接请求服务,这时通过 http.Request.RemoteAddr 字段 // 截取除去端口号的 ip 地址。 func ClientPublicIp(r *http.Request) string { var ip string for _, ip = range strings.Split(r.Header.Get("X-Forwarded-For"), ",") { ip = strings.TrimSpace(ip) if ip != "" && !HasLocalIPaddr(ip) { return ip } } ip = strings.TrimSpace(r.Header.Get("X-Real-Ip")) if ip != "" && !HasLocalIPaddr(ip) { return ip } if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil { if !HasLocalIPaddr(ip) { return ip } } return "" } // 判断是地址是否来自代理 func RemoteIp(r *http.Request) string { if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil { return ip } return "" } // 检测IP地址字符串是否内网地址 func HasLocalIPaddr(ip string) bool { return HasLocalIP(net.ParseIP(ip)) } // 检测IP地址是否内网地址 // tcp/ip协议中,专门保留了三个IP地址区域作为私有地址,其地址范围如下: // 10.0.0.0/8:10.0.0.0~10.255.255.255 // 172.16.0.0/12:172.16.0.0~172.31.255.255 // 192.168.0.0/16:192.168.0.0~192.168.255.255 func HasLocalIP(ip net.IP) bool { // for _, network := range localNetworks { // if network.Contains(ip) { // return true // } // } return ip.IsLoopback() }