Java-IP獲取測試

測試代碼

    @RequestMapping("/hello1")
    public Map getIp1(HttpServletRequest request) {

        Enumeration<String> names = request.getHeaderNames();
        ArrayList<String> array = new ArrayList<String>();
        while (names.hasMoreElements()){
            array.add(names.nextElement());
        }

        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < array.size(); i++) {
            String key = array.get(i);
            map.put(key, request.getHeader(key));
        }

        map.put("侯萬getRemoteAddr", request.getRemoteAddr());

        String ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
                // 根據(jù)網(wǎng)卡取本機(jī)配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ipAddress = inet.getHostAddress();
            }
        }
        
        // 對于通過多個(gè)代理的情況编曼,第一個(gè)IP為客戶端真實(shí)IP,多個(gè)IP按照','分割
        if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15
            if (ipAddress.indexOf(",") > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
            }
        }
        map.put("ipAddress", ipAddress);
        return map;
    }

資料1:

如果服務(wù)器使用了Nginx代理,需要設(shè)置Nginx的配置畜侦,才能獲取到IP元扔,因?yàn)榻?jīng)過反向代理后,由于在客戶端和web服務(wù)器之間增加了中間層旋膳,因此web服務(wù)器無法直接拿到客戶端的ip澎语,只能通過$remote_addr變量拿到的將是反向代理服務(wù)器的ip地址。
我在default.conf的配置是:

server {
    listen 443 ssl;  # 支持ipv4
    listen [:]:443 ssl;  # 支持ipv6
    
    location /hello {
        proxy_pass http://182.92.106.69:8848/hello1/;
        proxy_redirect    off;

        # 關(guān)鍵的四句代碼
        proxy_set_header  Host             $host:$server_port;
        proxy_set_header  X-Real-IP        $remote_addr;
        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Proto $scheme;
    }
}

Nginx中的幾個(gè)變量解釋:

  • $remote_addr代表客戶端的IP验懊,但它的值不是由客戶端提供的擅羞,而是服務(wù)端根據(jù)客戶端的ip指定的,icanhazip的原理也是這樣义图, 當(dāng)你的瀏覽器訪問某個(gè)網(wǎng)站時(shí)减俏,假設(shè)中間沒有任何代理,那么網(wǎng)站的web服務(wù)器就會把remote_addr設(shè)為你在公網(wǎng)暴露的IP碱工,如果你用了某個(gè)代理娃承,那么你的瀏覽器會先訪問這個(gè)代理,然后再由這個(gè)代理轉(zhuǎn)發(fā)到網(wǎng)站怕篷,這樣web服務(wù)器就會把remote_addr設(shè)為這臺代理機(jī)器的IP, 除非代理將你的IP附在請求header中一起轉(zhuǎn)交給web服務(wù)器历筝。
  • $proxy_add_x_forwarded_for 全局變量$proxy_add_x_forwarded_for包含客戶端請求頭中的X-Forwarded-For,與$remote_addr兩部分匙头,他們之間用逗號分開漫谷。X-Forwarded-For(簡稱XFF),X-Forwarded-For 是一個(gè) HTTP 擴(kuò)展頭部蹂析。RFC 2616 協(xié)議并沒有對它的定義舔示,它最開始是由 Squid 這個(gè)緩存代理軟件引入,用來表示 HTTP 請求端真實(shí) IP电抚。如今它已經(jīng)成為事實(shí)上的標(biāo)準(zhǔn)惕稻,被各大HTTP 代理、負(fù)載均衡等轉(zhuǎn)發(fā)服務(wù)廣泛使用蝙叛,并被寫入 RFC 7239(Forwarded HTTP Extension` 標(biāo)準(zhǔn)之中俺祠。
  • $proxy_set_header,可設(shè)置代理后 header
  • X-Real-IP 一般比如X-Real-IP這一個(gè)自定義頭部字段,通常被 HTTP 代理用來表示與它產(chǎn)生TCP 連接的設(shè)備 IP蜘渣,這個(gè)設(shè)備可能是其他代理淌铐,也可能是真正的請求端,這個(gè)要看經(jīng)過代理的層級次數(shù)或是是否始終將真實(shí)IP一路傳下來蔫缸。(牢記:任何客戶端傳上來的東西都是不可信的)

當(dāng)多層代理或使用CDN時(shí)腿准,如果代理服務(wù)器不把用戶的真實(shí)IP傳遞下去,那么服務(wù)器將永遠(yuǎn)不可能獲取到用戶的真實(shí)IP拾碌。

資料2:

上面存在問題是吐葱,可能一個(gè)基站,或者一個(gè)小區(qū)校翔,對外只有一個(gè)公共IP弟跑。因此這種情況下,同一ip出現(xiàn)數(shù)百用戶也是正常的防症。
典型的是:一個(gè)公司內(nèi)孟辑,大家共同用同一個(gè)網(wǎng)絡(luò),對外都是一個(gè)的公網(wǎng)IP蔫敲。

資料3:

私有的內(nèi)部組網(wǎng)IP段(可作為代碼直接判斷):

  • A類:10.0.0.0 — 10.255.255.255 10.0.0.0/8
  • B類:172.16.0.0 — 172.31.255.255 172.16.0.0/12
  • C類:192.168.0.0 — 192.168.255.255 192.168.0.0/16

資料4:

參考文檔:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扑浸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子燕偶,更是在濱河造成了極大的恐慌,老刑警劉巖础嫡,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件指么,死亡現(xiàn)場離奇詭異,居然都是意外死亡榴鼎,警方通過查閱死者的電腦和手機(jī)伯诬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巫财,“玉大人盗似,你說我怎么就攤上這事∑较睿” “怎么了赫舒?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長闽瓢。 經(jīng)常有香客問我接癌,道長,這世上最難降的妖魔是什么扣讼? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任缺猛,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘荔燎。我一直安慰自己耻姥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布有咨。 她就那樣靜靜地躺著琐簇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪摔吏。 梳的紋絲不亂的頭發(fā)上鸽嫂,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音征讲,去河邊找鬼据某。 笑死,一個(gè)胖子當(dāng)著我的面吹牛诗箍,可吹牛的內(nèi)容都是我干的癣籽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼滤祖,長吁一口氣:“原來是場噩夢啊……” “哼筷狼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起匠童,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤空厌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后劲腿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肴楷,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年扬绪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了竖独。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挤牛,死狀恐怖莹痢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情墓赴,我是刑警寧澤竞膳,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站竣蹦,受9級特大地震影響顶猜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜痘括,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一长窄、第九天 我趴在偏房一處隱蔽的房頂上張望滔吠。 院中可真熱鬧,春花似錦挠日、人聲如沸疮绷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冬骚。三九已至,卻和暖如春懂算,著一層夾襖步出監(jiān)牢的瞬間只冻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工计技, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喜德,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓垮媒,卻偏偏與公主長得像舍悯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子睡雇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容