go语言获取客户端ip的方法-创新互联
这篇文章将为大家详细讲解有关go语言获取客户端ip的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
创新互联主要为客户提供服务项目涵盖了网页视觉设计、VI标志设计、成都全网营销、网站程序开发、HTML5响应式重庆网站建设公司、成都做手机网站、微商城、网站托管及网站维护、WEB系统开发、域名注册、国内外服务器租用、视频、平面设计、SEO优化排名。设计、前端、后端三个建站步骤的完善服务体系。一人跟踪测试的建站服务标准。已经为木制凉亭行业客户提供了网站设计服务。ClientIP方法与ClientPublicIP方法的实现类似,只是一个按照http协议约定获取客户端ip, 一个按照约定格式查找到公网ip。
在网络与服务架构、业务逻辑复杂的环境中,按照http协议约定的方式,并非总能获取到真实的ip,在我们的业务中用户流量经由三方多层级转发(都是三方自己实现的http client) ,难免会出现一些纰漏,这时越往后的服务获取用户真实ip越加困难,你甚至不知道自己获取的ip是否是真实的。
但是我们的客户经由三方转发而来的流量,那么客户极大多数甚至排除测试之外都是公网用户,结合使用 ClientPublicIP 和 ClientIP 方法总能更好的获取用户的真实ip
// var r *http.Request ip := exnet.ClientPublicIP(r) if ip == ""{ ip = exnet.ClientIP(r) }
用上面的方法总能有效的获取用户真实的ip地址,下面分析下两个方法的具体实现。
// ClientIP 尽大努力实现获取客户端 IP 的算法。 // 解析 X-Real-IP 和 X-Forwarded-For 以便于反向代理(nginx 或 haproxy)可以正常工作。 func ClientIP(r *http.Request) string { xForwardedFor := r.Header.Get("X-Forwarded-For") ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0]) if ip != "" { return ip } ip = strings.TrimSpace(r.Header.Get("X-Real-Ip")) if ip != "" { return ip } if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil { return ip } return "" }
ClientIP首先读取X-Forwarded-For header中用 , 分隔的第一个ip地址,如果这个地址不存在,就会从X-Real-Ip header中获取,如果还是不存在,说明流量并非是由反向代理转发而来,而是客户端直接请求服务,这时通过http.Request.RemoteAddr字段截取除去端口号的ip地址。
这个方法很简单,就是按照http约定的格式获取,其中X-Forwarded-For和X-Real-Ip header由反向代理填充,例如nginx或 haproxy。
// ClientPublicIP 尽大努力实现获取客户端公网 IP 的算法。 // 解析 X-Real-IP 和 X-Forwarded-For 以便于反向代理(nginx 或 haproxy)可以正常工作。 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 != "" && !HasLocalIPddr(ip) { return ip } } ip = strings.TrimSpace(r.Header.Get("X-Real-Ip")) if ip != "" && !HasLocalIPddr(ip) { return ip } if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil { if !HasLocalIPddr(ip) { return ip } } return "" }
ClientPublicIP很简单,和ClientIP方法的读取顺序一样,只是试图中X-Forwarded-For列表中找到一个公网ip,如果没有检查X-Real-Ip 是否是一个公网ip,其次检查 http.Request.RemoteAddr 是否是公网ip,如果没有找到公网ip这返回一个空字符串。
这个方法可以让我们有机会优先获取到用户的公网 ip,往往公网 ip 对我们来说更有价值。
关于go语言获取客户端ip的方法就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
本文标题:go语言获取客户端ip的方法-创新互联
分享路径:http://ybzwz.com/article/egsss.html