nginx反向代理後應用程序如何獲取客戶端真實IP?

nginx反向代理後應用程序如何獲取客戶端真實IP?

2017年10月30日 10:32:03 it_0101 閱讀數:6200 標籤: tomcatjavawebnginx應用服務器servlet 更多

個人分類: 學習經驗服務器

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/it_0101/article/details/78390700

Nginx反向代理後,Servlet應用通過request.getRemoteAddr()取到的IP是Nginx的IP地址,並非客戶端真實IP,通過request.getRequestURL()獲取的域名、協議、端口都是Nginx訪問Web應用時的域名、協議、端口,而非客戶端瀏覽器地址欄上的真實域名、協議、端口。

Nginx的反向代理實際上是客戶端和真實的應用服務器之間的一個橋樑,客戶端(一般是瀏覽器)訪問Nginx服務器,Nginx再去訪問Web應用服務器。對於Web應用來說,這次HTTP請求的客戶端是Nginx而非真實的客戶端瀏覽器,如果不做特殊處理的話,Web應用會把Nginx當作請求的客戶端,獲取到的客戶端信息就是Nginx的一些信息。

解決這個問題要從兩個方面來解決: 
1. 由於Nginx是代理服務器,所有客戶端請求都從Nginx轉發到Tomcat,如果Nginx不把客戶端真實IP、域名、協議、端口告訴Tomcat,那麼Tomcat應用是永遠不會知道這些信息的,所以需要Nginx配置一些HTTP Header來將這些信息告訴被代理的Tomcat; 
2. Tomcat這一端,不能再傻乎乎的獲取直接和它連接的客戶端(也就是Nginx)的信息,而是要從Nginx傳遞過來的HTTP Header中獲取客戶端信息。

 

 

Nginx

 

在代理的每個location處添加以下配置:

 
  1. proxy_set_header Host $http_host;

  2. proxy_set_header X-Real-IP $remote_addr;

  3. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  4. proxy_set_header X-Forwarded-Proto $scheme;

  • 1
  • 2
  • 3
  • 4

解釋以下上面的配置,以上配置是在Nginx反向代理的時候,添加一些請求Header。 
1. Host包含客戶端真實的域名和端口號; 
2. X-Forwarded-Proto表示客戶端真實的協議(http還是https); 
3. X-Real-IP表示客戶端真實的IP; 
4. X-Forwarded-For這個Header和X-Real-IP類似,但它在多層代理時會包含真實客戶端及中間每個代理服務器的IP。

配置到這一步後,還不能徹底解決問題。tomcat也需要配置

如果你在網上搜索“Java如何獲取客戶端真實IP”,搜索到的解決方案大多是通過獲取HTTP請求頭request.getHeader("X-Forwarded-For")request.getHeader("X-Real-IP")來實現,也就是上面在Nginx上配置的Header,這種方案獲取的結果的確是正確的,但覺得並不優雅。因爲既然Servlet API提供了request.getRemoteAddr()方法獲取客戶端IP,那麼無論有沒有用反向代理對於代碼編寫者來說應該是透明的。下面介紹一種更加優雅的方式。

 

使用Tomcat作爲應用服務器,可以通過配置Tomcat的server.xml文件,在Host元素內最後加入:即可

<Valve className="org.apache.catalina.valves.RemoteIpValve" />
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章