中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中獲取客戶端真實IP的方法

發布時間:2021-02-02 14:45:31 來源:億速云 閱讀:716 作者:小新 欄目:編程語言

這篇文章將為大家詳細講解有關Java中獲取客戶端真實IP的方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

Java中獲取客戶端真實IP的方法

<!-- more -->

nginx配置

首先,一個請求肯定是可以分為請求頭和請求體的,而我們客戶端的IP地址信息一般都是存儲在請求頭里的。如果你的服務器有用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

在《實戰nginx》中,有這么一句話:

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

這句話的意思是說,當你使用了nginx反向服務器后,在web端使用request.getRemoteAddr()(本質上就是獲取$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開發的,用于識別通過HTTP代理或負載平衡器原始IP一個連接到Web服務器的客戶機地址的非rfc標準,如果有做X-Forwarded-For設置的話,每次經過proxy轉發都會有記錄,格式就是client1,proxy1,proxy2以逗號隔開各個地址,由于它是非rfc標準,所以默認是沒有的,需要強制添加。在默認情況下經過proxy轉發的請求,在后端看來遠程地址都是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上,并且都使用了這段配置,那你會發現在web服務器端通過request.getAttribute("X-Forwarded-For")獲得的將會是客戶端ip和第一臺nginx的ip。

那么$proxy_add_x_forwarded_for又是什么?

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

舉個例子,有一個web應用,在它之前通過了兩個nginx轉發,www.linuxidc.com即用戶訪問該web通過兩臺nginx。

在第一臺nginx中,使用:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

現在的$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;

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

服務器獲取真實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開發的字段,只有在通過了HTTP代理或者負載均衡服務器時才會添加該項。

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

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

HTTP_CLIENT_IP

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

這是普通的 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 還沒普及的年代,企業內網假設的 http 透明代理,傳給服務器的 header,只有極少數廠家用過,從來不是標準,也從來沒成為過事實標準。
(大家最熟悉的事實標準就是 x-forwarded-for)

后來出現的 web proxy 也沒見用過這個 header。

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

HTTP_X_FORWARDED_FOR

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

關于“Java中獲取客戶端真實IP的方法”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

酒泉市| 内乡县| 河北省| 金门县| 荔波县| 石河子市| 营山县| 江津市| 桃江县| 阳谷县| 射阳县| 凤翔县| 灵山县| 景东| 宁德市| 万全县| 城步| 义马市| 万源市| 陵川县| 丰顺县| 景洪市| 江华| 榆林市| 鸡泽县| 汶川县| 大邑县| 来凤县| 榕江县| 什邡市| 新余市| 沂源县| 沁水县| 阿坝| 筠连县| 额济纳旗| 嘉荫县| 洛隆县| 海口市| 行唐县| 兴国县|