一、问题描述
http.Request
下的方法 RemoteAddr()
可以获取客户端的地址和端口号,最近的一个项目中用到了这个方法。
使用过程中一直都没有什么问题,但是当项目上线之后就发现不管怎么获取 ip,客户端地址都是 127.0.0.1
。
对于这个问题一直百思不得其解,最后搞了半天才发现是 nginx
的原因。
因为线上项目使用 nginx 做了反向代理,所以导致服务端每次获取的都是 nginx 的地址,即 127.0.0.1
。
关于这个问题的具体的内容可以查看:HTTP 协议中的 X-Real-IP, X-Forwarded-For 和 remote_addr 头
二、解决方法
当 http 请求不存在代理的时候,使用这个方法时没有问题的,但是在有代理的情况下,就只能通过其他的方法来获取了。
如果是 nginx
,可以在代理的代码块加上以下代码:
1 2 3 4 5 6 7 |
location / { ... proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass https://192.168.234.131; ... } |
在 nginx 转发前把真实地址设置到 X-Real-IP
和 X-Forwarded-For
两个请求头上,然后根据需要再从它们的值获取。
1 2 3 4 5 6 7 8 9 10 11 |
func getCurrentIP(r http.Request)(string){ // 这里也可以通过 X-Forwarded-For 请求头的第一个值作为用户的 ip // 但是要注意的是这两个请求头代表的 ip 都有可能是伪造的 ip := r.Header.Get("X-Real-IP") if ip == ""{ // 当请求头不存在即不存在代理时直接获取 ip ip = strings.Split(r.RemoteAddr, ":")[0] } return ip } |
评论