Files
ipx/get_ip.go
2026-05-03 23:41:50 +08:00

61 lines
1.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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/810.0.0.010.255.255.255
// 172.16.0.0/12172.16.0.0172.31.255.255
// 192.168.0.0/16192.168.0.0192.168.255.255
func HasLocalIP(ip net.IP) bool {
// for _, network := range localNetworks {
// if network.Contains(ip) {
// return true
// }
// }
return ip.IsLoopback()
}