這篇文章將為大家詳細講解有關(guān)go語言獲取客戶端ip的方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
創(chuàng)新互聯(lián)公司技術(shù)團隊十余年來致力于為客戶提供成都網(wǎng)站制作、做網(wǎng)站、高端網(wǎng)站設(shè)計、網(wǎng)絡(luò)營銷推廣、搜索引擎SEO優(yōu)化等服務(wù)。經(jīng)過多年發(fā)展,公司擁有經(jīng)驗豐富的技術(shù)團隊,先后服務(wù)、推廣了成百上千家網(wǎng)站,包括各類中小企業(yè)、企事單位、高校等機構(gòu)單位。
ClientIP方法與ClientPublicIP方法的實現(xiàn)類似,只是一個按照http協(xié)議約定獲取客戶端ip, 一個按照約定格式查找到公網(wǎng)ip。
在網(wǎng)絡(luò)與服務(wù)架構(gòu)、業(yè)務(wù)邏輯復(fù)雜的環(huán)境中,按照http協(xié)議約定的方式,并非總能獲取到真實的ip,在我們的業(yè)務(wù)中用戶流量經(jīng)由三方多層級轉(zhuǎn)發(fā)(都是三方自己實現(xiàn)的http client) ,難免會出現(xiàn)一些紕漏,這時越往后的服務(wù)獲取用戶真實ip越加困難,你甚至不知道自己獲取的ip是否是真實的。
但是我們的客戶經(jīng)由三方轉(zhuǎn)發(fā)而來的流量,那么客戶極大多數(shù)甚至排除測試之外都是公網(wǎng)用戶,結(jié)合使用 ClientPublicIP 和 ClientIP 方法總能更好的獲取用戶的真實ip
// var r *http.Request ip := exnet.ClientPublicIP(r) if ip == ""{ ip = exnet.ClientIP(r) }
用上面的方法總能有效的獲取用戶真實的ip地址,下面分析下兩個方法的具體實現(xiàn)。
// ClientIP 盡最大努力實現(xiàn)獲取客戶端 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中獲取,如果還是不存在,說明流量并非是由反向代理轉(zhuǎn)發(fā)而來,而是客戶端直接請求服務(wù),這時通過http.Request.RemoteAddr字段截取除去端口號的ip地址。
這個方法很簡單,就是按照http約定的格式獲取,其中X-Forwarded-For和X-Real-Ip header由反向代理填充,例如nginx或 haproxy。
// ClientPublicIP 盡最大努力實現(xiàn)獲取客戶端公網(wǎng) 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列表中找到一個公網(wǎng)ip,如果沒有檢查X-Real-Ip 是否是一個公網(wǎng)ip,其次檢查 http.Request.RemoteAddr 是否是公網(wǎng)ip,如果沒有找到公網(wǎng)ip這返回一個空字符串。
這個方法可以讓我們有機會優(yōu)先獲取到用戶的公網(wǎng) ip,往往公網(wǎng) ip 對我們來說更有價值。
關(guān)于go語言獲取客戶端ip的方法就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
分享標題:go語言獲取客戶端ip的方法
轉(zhuǎn)載來于:http://jinyejixie.com/article38/poedpp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、電子商務(wù)、定制開發(fā)、商城網(wǎng)站、動態(tài)網(wǎng)站、軟件開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)