這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
一、問題描述
http.Request
下的方法RemoteAddr()
可以擷取用戶端的地址和連接埠號碼,最近的一個項目中用到了這個方法。
使用過程中一直都沒有什麼問題,但是當項目上線之後就發現不管怎麼擷取ip,用戶端地址都是127.0.0.1
。
對於這個問題一直百思不得其解,最後搞了半天才發現是nginx
的原因。
因為線上項目使用nginx做了反向 Proxy,所以導致服務端每次擷取的都是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 http://192.168.234.131; ... }
|
在nginx轉寄前把真真實位址設定到X-Real-IP
和X-Forwarded-For
兩個要求標頭上,然後根據需要再從它們的值擷取。
1 2 3 4 5 6 7 8 9 10
|
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 }
|