golang如何获取客户端ip?

golang获取客户端ip的方法:

ClientIP方法与ClientPublicIP方法的实现类似,只是一个按照http协议约定获取客户端ip, 一个按照约定格式查找到公网ip。

在网络与服务架构、业务逻辑复杂的环境中,按照http协议约定的方式,并非总能获取到真实的ip,在我们的业务中用户流量经由三方多层级转发(都是三方自己实现的http client) ,难免会出现一些纰漏,这时越往后的服务获取用户真实ip越加困难,你甚至不知道自己获取的ip是否是真实的。

但是我们的客户经由三方转发而来的流量,那么客户极大多数甚至排除测试之外都是公网用户,结合使用 ClientPublicIP 和 ClientIP 方法总能更好的获取用户的真实ip

// var r *http.Requestip := 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 stringfor _, 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语言教程》

更多相关文章

  1. go语言中自定义包的方法
  2. go语言中的结构体与方法详解
  3. 详解 Go 语言中的方法
  4. Golang中使用JSON时区分空字段和未设置字段的方法
  5. 详解Go 语言中的方法
  6. golang实现二倍均值算法和抢红包的方法
  7. go语言grpc环境搭建的方法详解
  8. 关于Go语言的http/2服务器功能及客户端使用方法
  9. 【发布了Go-carbon1.1.1版本】完善对主流ORM的支持,新增公共方法

随机推荐

  1. (原)Eclipse的java中文件读写
  2. ListView小知识整理:滑动背景、Item间隙等
  3. Android学习笔记6——基本布局
  4. ContentProvider详解
  5. android 录像/打开video文件
  6. Android曲线绘制demo
  7. Android 设备指纹
  8. Jenkins构建时’Users/Mac/Library/Andro
  9. Android: android source code online
  10. Android之MVP 模式:简单易懂的介绍方式