欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java面試之如何獲取客戶端真實(shí)IP

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

前言

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

<!-- more -->

nginx配置

首先,一個請求肯定是可以分為請求頭和請求體的,而我們客戶端的IP地址信息一般都是存儲在請求頭里的。如果你的服務(wù)器有用Nginx做負(fù)載均衡的話,你需要在你的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

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

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

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

proxy_set_header X-Real-IP $remote_addr;

X-Forwarded-For

X-Forwarded-For變量,這是一個squid開發(fā)的,用于識別通過HTTP代理或負(fù)載平衡器原始IP一個連接到Web服務(wù)器的客戶機(jī)地址的非rfc標(biāo)準(zhǔn),如果有做X-Forwarded-For設(shè)置的話,每次經(jīng)過proxy轉(zhuǎn)發(fā)都會有記錄,格式就是client1,proxy1,proxy2以逗號隔開各個地址,由于它是非rfc標(biāo)準(zhǔn),所以默認(rèn)是沒有的,需要強(qiáng)制添加。在默認(rèn)情況下經(jīng)過proxy轉(zhuǎn)發(fā)的請求,在后端看來遠(yuǎn)程地址都是proxy端的ip 。也就是說在默認(rèn)情況下我們使用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里去,注意是增加,而不是覆蓋,當(dāng)然由于默認(rèn)的X-Forwarded-For值是空的,所以我們總感覺X-Forwarded-For的值就等于$proxy_add_x_forwarded_for的值,實(shí)際上當(dāng)你搭建兩臺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變量的值就是用戶的真實(shí)的ip地址了。

到了第二臺nginx,使用:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

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

服務(wù)器獲取真實(shí)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才是真實(shí)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代理或者負(fù)載均衡服務(wù)器時才會添加該項(xiàng)。

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ù)廠家用過,從來不是標(biāo)準(zhǔn),也從來沒成為過事實(shí)標(biāo)準(zhǔn)。
(大家最熟悉的事實(shí)標(biāo)準(zhǔn)就是 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的請求端真實(shí)的IP,只有在通過了HTTP 代理(比如APACHE代理)或者負(fù)載均衡服務(wù)器時才會添加該項(xiàng)。它不是RFC中定義的標(biāo)準(zhǔn)請求頭信息,在squid緩存代理服務(wù)器開發(fā)文檔中可以找到該項(xiàng)的詳細(xì)介紹。如果有該條信息, 說明您使用了代理服務(wù)器,地址就是后面的數(shù)值。可以偽造。標(biāo)準(zhǔn)格式如下:X-Forwarded-For: client1, proxy1, proxy2

總結(jié)

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

相關(guān)文章

  • springboot 傳參校驗(yàn)@Valid及對其的異常捕獲方式

    springboot 傳參校驗(yàn)@Valid及對其的異常捕獲方式

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

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

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

    SpringBoot的@RestControllerAdvice作用詳解

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

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

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

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

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

    Mybatis-Plus 通用CRUD的詳細(xì)操作

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

    Java中淺拷貝和深拷貝詳解

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

    Java位運(yùn)算知識點(diǎn)詳解

    這篇文章給大家分享了關(guān)于Java位運(yùn)算的相關(guān)知識點(diǎn)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。
    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)式編程實(shí)踐

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

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

最新評論