You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

81 lines
1.6 KiB

package utils
import (
"errors"
"log/slog"
"net"
"strings"
"github.com/gin-gonic/gin"
)
func GetIpAddress(c *gin.Context) (ipAddress string) {
// 尝试从不同的HTTP头部获取客户端IP
ipAddress = c.Request.Header.Get("X-Real-IP")
if ipAddress == "" || strings.EqualFold(ipAddress, "unknown") {
ipAddress = c.Request.Header.Get("X-Forwarded-For")
if ipAddress != "" {
ipAddress = strings.Split(ipAddress, ",")[0]
} else {
ipAddress = c.Request.Header.Get("Proxy-Client-IP")
if ipAddress == "" {
ipAddress = c.Request.Header.Get("WL-Proxy-Client-IP")
}
}
}
if ipAddress == "" {
ipAddress = c.ClientIP()
}
// 检测到是本机 IP, 读取其局域网 IP 地址
if strings.HasPrefix(ipAddress, "127.0.0.1") || strings.HasPrefix(ipAddress, "[::1]") {
ip, err := externalIP()
if err != nil {
slog.Error("GetIpAddress, externalIP, err: ", "error:", err)
}
ipAddress = ip.String()
}
return ipAddress
}
// 获取非 127.0.0.1 的局域网 IP
func externalIP() (net.IP, error) {
ifaces, err := net.Interfaces()
if err != nil {
return nil, err
}
for _, iface := range ifaces {
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
continue
}
addrs, err := iface.Addrs()
if err != nil {
return nil, err
}
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
if ip == nil || ip.IsLoopback() {
continue
}
ip = ip.To4()
if ip != nil {
return ip, nil
}
}
}
return nil, errors.New("no non-loopback addresses available")
}