最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java面試之如何獲取客戶端真實IP

 更新時間:2019年09月22日 16:05:56   作者:death00  
這篇文章主要給大家介紹了關(guān)于Java面試之如何獲取客戶端真實IP的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Java具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

前言

在進行一些小游戲開發(fā)時,我們經(jīng)常比較關(guān)注的一個功能便是分享。針對分享,我們希望能根據(jù)各個城市或者地區(qū),能有不同的分享文案,辨識地區(qū)的功能如果由服務(wù)器來完成的話,我們就需要知道客戶端的真實IP。今天我們就來看看服務(wù)器是如何獲取到客戶端的真實IP的。

<!-- more -->

nginx配置

首先,一個請求肯定是可以分為請求頭和請求體的,而我們客戶端的IP地址信息一般都是存儲在請求頭里的。如果你的服務(wù)器有用Nginx做負載均衡的話,你需要在你的location里面配置X-Real-IP和X-Forwarded-For請求頭:

  location ^~ /your-service/ {
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://localhost:60000/your-service/;
  }

X-Real-IP

在《實戰(zhàn)nginx》中,有這么一句話:

經(jīng)過反向代理后,由于在客戶端和web服務(wù)器之間增加了中間層,因此web服務(wù)器無法直接拿到客戶端的ip,通過$remote_addr變量拿到的將是反向代理服務(wù)器的ip地址。

這句話的意思是說,當你使用了nginx反向服務(wù)器后,在web端使用request.getRemoteAddr()(本質(zhì)上就是獲取$remote_addr),取得的是nginx的地址,即$remote_addr變量中封裝的是nginx的地址,當然是沒法獲得用戶的真實ip的。但是,nginx是可以獲得用戶的真實ip的,也就是說nginx使用$remote_addr變量時獲得的是用戶的真實ip,如果我們想要在web端獲得用戶的真實ip,就必須在nginx里作一個賦值操作,即我在上面的配置:

proxy_set_header X-Real-IP $remote_addr;

X-Forwarded-For

X-Forwarded-For變量,這是一個squid開發(fā)的,用于識別通過HTTP代理或負載平衡器原始IP一個連接到Web服務(wù)器的客戶機地址的非rfc標準,如果有做X-Forwarded-For設(shè)置的話,每次經(jīng)過proxy轉(zhuǎn)發(fā)都會有記錄,格式就是client1,proxy1,proxy2以逗號隔開各個地址,由于它是非rfc標準,所以默認是沒有的,需要強制添加。在默認情況下經(jīng)過proxy轉(zhuǎn)發(fā)的請求,在后端看來遠程地址都是proxy端的ip 。也就是說在默認情況下我們使用request.getAttribute("X-Forwarded-For")獲取不到用戶的ip,如果我們想要通過這個變量獲得用戶的ip,我們需要自己在nginx添加配置:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

意思是增加一個$proxy_add_x_forwarded_for到X-Forwarded-For里去,注意是增加,而不是覆蓋,當然由于默認的X-Forwarded-For值是空的,所以我們總感覺X-Forwarded-For的值就等于$proxy_add_x_forwarded_for的值,實際上當你搭建兩臺nginx在不同的ip上,并且都使用了這段配置,那你會發(fā)現(xiàn)在web服務(wù)器端通過request.getAttribute("X-Forwarded-For")獲得的將會是客戶端ip和第一臺nginx的ip。

那么$proxy_add_x_forwarded_for又是什么?

$proxy_add_x_forwarded_for變量包含客戶端請求頭中的X-Forwarded-For與$remote_addr兩部分,他們之間用逗號分開。

舉個例子,有一個web應(yīng)用,在它之前通過了兩個nginx轉(zhuǎn)發(fā),www.linuxidc.com即用戶訪問該web通過兩臺nginx。

在第一臺nginx中,使用:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

現(xiàn)在的$proxy_add_x_forwarded_for變量的X-Forwarded-For部分是空的,所以只有$remote_addr,而$remote_addr的值是用戶的ip,于是賦值以后,X-Forwarded-For變量的值就是用戶的真實的ip地址了。

到了第二臺nginx,使用:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

現(xiàn)在的$proxy_add_x_forwarded_for變量,X-Forwarded-For部分包含的是用戶的真實ip,$remote_addr部分的值是上一臺nginx的ip地址,于是通過這個賦值以后現(xiàn)在的X-Forwarded-For的值就變成了“用戶的真實ip,第一臺nginx的ip”,這樣就清楚了吧。

服務(wù)器獲取真實IP

代碼為:

 public static String getIpAddress(HttpServletRequest request) {
 String Xip = request.getHeader("X-Real-IP");
 String XFor = request.getHeader("X-Forwarded-For");

 if (!Strings.isNullOrEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
  //多次反向代理后會有多個ip值,第一個ip才是真實ip
  int index = XFor.indexOf(",");
  if (index != -1) {
  return XFor.substring(0, index);
  } else {
  return XFor;
  }
 }
 XFor = Xip;
 if (!Strings.isNullOrEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
  return XFor;
 }
 if (Strings.nullToEmpty(XFor).trim().isEmpty() || "unknown".equalsIgnoreCase(XFor)) {
  XFor = request.getHeader("Proxy-Client-IP");
 }
 if (Strings.nullToEmpty(XFor).trim().isEmpty() || "unknown".equalsIgnoreCase(XFor)) {
  XFor = request.getHeader("WL-Proxy-Client-IP");
 }
 if (Strings.nullToEmpty(XFor).trim().isEmpty() || "unknown".equalsIgnoreCase(XFor)) {
  XFor = request.getHeader("HTTP_CLIENT_IP");
 }
 if (Strings.nullToEmpty(XFor).trim().isEmpty() || "unknown".equalsIgnoreCase(XFor)) {
  XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
 }
 if (Strings.nullToEmpty(XFor).trim().isEmpty() || "unknown".equalsIgnoreCase(XFor)) {
  XFor = request.getRemoteAddr();
 }
 return XFor;
 }

我們來看看各個請求頭的含義

X-Real-IP

nginx代理一般會加上此請求頭。

X-FORWARDED-FOR

這是一個Squid開發(fā)的字段,只有在通過了HTTP代理或者負載均衡服務(wù)器時才會添加該項。

Proxy-Client-IP 和 WL-Proxy-Client-IP

這個一般是經(jīng)過apache http服務(wù)器的請求才會有,用apache http做代理時一般會加上Proxy-Client-IP請求頭,而WL-Proxy-Client-IP是它的weblogic插件加上的頭。

HTTP_CLIENT_IP

有些代理服務(wù)器會加上此請求頭。在網(wǎng)上搜了一下,有一個說法是:

這是普通的 http header,偽造起來很容易,不要輕易信任用戶輸入。

curl -H 'client-ip: 8.8.8.8' lidian.club/phpinfo.php | grep _SERVER
你就能看到 _SERVER["HTTP_CLIENT_IP"] 了。

client-ip 和 client-host 是在 NAPT 還沒普及的年代,企業(yè)內(nèi)網(wǎng)假設(shè)的 http 透明代理,傳給服務(wù)器的 header,只有極少數(shù)廠家用過,從來不是標準,也從來沒成為過事實標準。
(大家最熟悉的事實標準就是 x-forwarded-for)

后來出現(xiàn)的 web proxy 也沒見用過這個 header。

TCP/IP Illustrated Vol 3 沒有講過這個 header,網(wǎng)上的傳言不可信。
可考的最早痕跡出現(xiàn)在2005年,日本一部 Perl/CGI 秘籍(9784798010779,270頁)通過 client-ip 與 via 兩個 header 屏蔽代理用戶訪問。

HTTP_X_FORWARDED_FOR

簡稱XFF頭,它代表客戶端,也就是HTTP的請求端真實的IP,只有在通過了HTTP 代理(比如APACHE代理)或者負載均衡服務(wù)器時才會添加該項。它不是RFC中定義的標準請求頭信息,在squid緩存代理服務(wù)器開發(fā)文檔中可以找到該項的詳細介紹。如果有該條信息, 說明您使用了代理服務(wù)器,地址就是后面的數(shù)值??梢詡卧?。標準格式如下:X-Forwarded-For: client1, proxy1, proxy2

總結(jié)

以上就是我在處理客戶端真實IP的方法,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。

相關(guān)文章

  • springboot 傳參校驗@Valid及對其的異常捕獲方式

    springboot 傳參校驗@Valid及對其的異常捕獲方式

    這篇文章主要介紹了springboot 傳參校驗@Valid及對其的異常捕獲方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • IntelliJ中高效重構(gòu)的10個快捷方式詳解

    IntelliJ中高效重構(gòu)的10個快捷方式詳解

    這篇文章主要為大家介紹了IntelliJ中高效重構(gòu)的10個快捷方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • SpringBoot的@RestControllerAdvice作用詳解

    SpringBoot的@RestControllerAdvice作用詳解

    這篇文章主要介紹了SpringBoot的@RestControllerAdvice作用詳解,@RestContrllerAdvice是一種組合注解,由@ControllerAdvice,@ResponseBody組成,本質(zhì)上就是@Component,需要的朋友可以參考下
    2024-01-01
  • Java中5種異步實現(xiàn)的方式詳解

    Java中5種異步實現(xiàn)的方式詳解

    同步操作如果遇到一個耗時的方法,需要阻塞等待,那么我們有沒有辦法解決呢?讓它異步執(zhí)行,下面我會詳解異步及實現(xiàn),需要的可以參考一下
    2022-09-09
  • Java響應(yīng)式編程之handle用法解析

    Java響應(yīng)式編程之handle用法解析

    這篇文章主要介紹了Java響應(yīng)式編程之handle用法解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Mybatis-Plus 通用CRUD的詳細操作

    Mybatis-Plus 通用CRUD的詳細操作

    這篇文章主要介紹了Mybatis-Plus 通用CRUD的詳細操作,包括插入操作,更新操作及刪除操作等,針對每種操作通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2021-09-09
  • Java中淺拷貝和深拷貝詳解

    Java中淺拷貝和深拷貝詳解

    大家好,本篇文章主要講的是Java中淺拷貝和深拷貝詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Java位運算知識點詳解

    Java位運算知識點詳解

    這篇文章給大家分享了關(guān)于Java位運算的相關(guān)知識點內(nèi)容,有興趣的朋友們可以學習參考下。
    2018-09-09
  • SpringBoot AOP控制Redis自動緩存和更新的示例

    SpringBoot AOP控制Redis自動緩存和更新的示例

    今天小編就為大家分享一篇關(guān)于SpringBoot AOP控制Redis自動緩存和更新的示例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • springboot3+r2dbc響應(yīng)式編程實踐

    springboot3+r2dbc響應(yīng)式編程實踐

    本文主要介紹了springboot3+r2dbc響應(yīng)式編程實踐,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02

最新評論

蕉岭县| 张家口市| 馆陶县| 全南县| 乌海市| 曲水县| 航空| 乐业县| 奉节县| 铅山县| 堆龙德庆县| 怀远县| 广灵县| 民权县| 米泉市| 河曲县| 孟津县| 潞西市| 云霄县| 钟山县| 陇川县| 富宁县| 湖北省| 吉安市| 芮城县| 涿州市| 舒兰市| 曲沃县| 临洮县| 德格县| 南丰县| 呼伦贝尔市| 安图县| 措勤县| 华坪县| 常熟市| 沙坪坝区| 平武县| 大田县| 容城县| 玉山县|