在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。

如果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为 http://www.bt285.cn / 的URL时,用request.getRemoteAddr()方法Java获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。

经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问http://www.5q520.cn /index.jsp/ 时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问http://192.168.1.110:2046/index.jsp ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过request.getRemoteAddr()的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。

于是可得出Java获取IP地址真实地址的方法一:

1 public String getRemortIP(HttpServletRequest request) {      
2     if (request.getHeader("x-forwarded-for") == null) {      
3         return request.getRemoteAddr();      
4     }      
5     return request.getHeader("x-forwarded-for");      
6 }

可是当我访问http://www.5a520.cn /index.jsp/ 时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1 或 192.168.1.110了,而我访问http://192.168.1.110:2046/index.jsp 时,则能返回客户端的真实IP地址,写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off  则:X-Forwarded-For: unknown

于是可得出获得Java获取IP地址的方法二:

 

1  public String getIpAddr(HttpServletRequest request) {      
 2 
 3        String ip = request.getHeader("x-forwarded-for");      
 4 
 5        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {      
 6 
 7            ip = request.getHeader("Proxy-Client-IP");      
 8 
 9        }      
10 
11        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {      
12 
13            ip = request.getHeader("WL-Proxy-Client-IP");      
14 
15        }      
16 
17        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {      
18 
19            ip = request.getRemoteAddr();      
20 
21        }      
22 
23        return ip;      
24 
25    }

 

 

可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?

答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。

如:

X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100

用户真实IP为: 192.168.1.110

通过这样的测试

JSP

里,

获取客户端的

IP

地址的方法是:

request.getRemoteAddr()

这种方法在大

部分情况下都是有效的。但是在通过了

Apache,Squid

等反向代理软件就不能获取到客户端

的真实

IP

地址了。

 

如果使用了反向代理软件,将

http://192.168.1.110:2046/ 

URL

反向代理为

 

http://www.bt285.cn 

URL

时,用

request.getRemoteAddr()

方法

Java

获取的

IP

地址

是:

127.0.0.1 

 

192.168.1.110

,而并不是客户端的真实IP。

 

经过代理以后,

由于在客户端和服务之间增加了中间层,

因此服务器无法直接拿到客户

端的

IP

,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的

HTTP

头信息中,增加了

X

FORWARDED

FOR

信息。用以跟踪原有的客户端

IP

地址和原来客

户端请求的服务器地址。当我们访问

http://www.5q520.cn /index.jsp/ 

时,其实并不是

我们浏览器真正访问到了服务器上的

index.jsp

文件,而是先由代理服务器去访问

http://192.168.1.110:2046/index.jsp 

代理服务器再将访问到的结果返回给我们的浏览

器,因为是代理服务器去访问

index.jsp

的,所以

index.jsp

中通过

request.getRemoteAddr()

的方法获取的

IP

实际上是代理服务器的地址,并不是客户端的

IP

地址。

 

于是可得出

Java

获取

IP

地址真实地址的方法一:

 

1.

public
 String getRemortIP(HttpServletRequest request) {

     

2.

 

  

if
 (request.getHeader(
"x-forwarded-for"
) == 
null
) {

3.

return
 request.getRemoteAddr();

4.

 

  }       

5.

return
 request.getHeader(
"x-forwarded-for"
);       
6.
 
 }

可是当我访问

http://www.5a520.cn 

/index.jsp/ 

时,

返回的

IP

地址始终是

unknown

也并不是如上所示的

127.0.0.1 

 

192.168.1.110

了,而我访问

http://192.168.1.110:2046/index.jsp 

时,则能返回客户端的真实

IP

地址,写了个方法

去验证。原因出在了

Squid

上。

squid.conf 

的配制文件

 

forwarded_for 

项默认是为

on

如果

 forwarded_for 

设成了

 off  

则:

X-Forwarded-For: unknown 

于是可得出获得

Java

获取

IP

地址的方法二:

 

7.

public
 String getIpAddr(HttpServletRequest request) {

   

8.

 

String ip = request.getHeader(
"x-forwarded-for"
);

     

9.

 

       

if
(ip == 
null
 || ip.length() == 
0
 || 
"unknown"
.equalsIgnoreCa
se(ip)) {

   

10.

 

ip = request.getHeader(
"Proxy-Client-IP"
);

    

11.

 

       }       

12.


if
(ip == 
null
 || ip.length() == 
0
 || 
"unknown"
.equalsIgnoreCa
se(ip)) {

  

13.

 

ip = request.getHeader(
"WL-Proxy-Client-IP"
);

      

14.

 

       }       

15.

 

       

if
(ip == 
null
 || ip.length() == 
0
 || 
"unknown"
.equalsIgnoreCa
se(ip)) {

  

16.

 

    

ip = request.getRemoteAddr();

17.

 

       }       

18.

 

       

return
 ip;

   

19.

 

   }    

可是,

如果通过了多级反向代理的话,

X-Forwarded-For

的值并不止一个,

而是一串

IP

值,究竟哪个才是真正的用户端的真实

IP

呢?

 

答案是取

X-Forwarded-For

中第一个非

unknown

的有效

IP

字符串。

 

如:

 

X-Forwarded-For

192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100 

用户真实

IP

为:

 192.168.1.110 

通过这样的测试