Go语言获取客户端真实IP
在一些需求中,服务器需要记录客户端的ip地址,要获取ip地址,则需要有http.Request的对象参数传入,以下代码直接放在util中使用。
文件名:ip_utils.go
package utils
import (
"context"
"github.com/spf13/cast"
"net"
"net/http"
"strings"
)
// GetClientRealIp 获取客户端的真实 IP 地址
func GetClientRealIp(r *http.Request) (string, bool) {
headers := []string{
"X-Forwarded-For",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"X-Real-Ip",
}
for _, header := range headers {
ip := r.Header.Get(header)
if ip != "" {
// X-Forwarded-For 可能包含多个 IP 地址,用逗号分隔,取第一个有效的
ips := strings.Split(ip, ",")
for _, ipPart := range ips {
ipPart = strings.TrimSpace(ipPart)
if isValidIp(ipPart) {
return ipPart, true
}
}
}
}
// 如果没有获取到有效的 IP,则返回远程地址
ip, _, _ := net.SplitHostPort(r.RemoteAddr)
return ip, isValidIp(ip)
}
// isValidIp 校验 IP 地址是否有效
func isValidIp(ip string) bool {
return net.ParseIP(ip) != nil
}
func GetHeaderAsString(ctx context.Context, key string) (string, bool) {
strAny := ctx.Value(key)
if strAny != nil {
strSlice := cast.ToStringSlice(strAny)
if len(strSlice) > 0 {
return strSlice[0], true
}
}
return "", false
}
还有一个需求是,如果还需要获取客户端的请求路由,则是
r.URL.Path