admin管理员组

文章数量:1530254

2023年12月11日发(作者:)

获取客户端真实IP地址

Java-Web获取客户端真实IP:

  

发生的场景:服务器端接收客户端请求的时候,一般需要进行签名验证,客户端IP限定等情况,在进行客户端IP限定的时候,需要首先获取

该真实的IP。

一般分为两种情况:

  方式一、客户端未经过代理,直接访问服务器端(nginx,squid,haproxy);

  方式二、客户端通过多级代理,最终到达服务器端(nginx,squid,haproxy);

客户端请求信息都包含在HttpServletRequest中,可以通过方法getRemoteAddr()获得该客户端IP。

  方式一形式,可以直接获得该客户端真实IP。

  方式二中通过代理的形式,此时经过多级反向的代理,通过方法getRemoteAddr()得不到客户端真实IP,可以通过x-forwarded-for获得转

发后请求信息。当客户端请求被转发,IP将会追加在其后并以逗号隔开,例如:10.47.103.13,4.2.2.2,10.96.112.230。

请求中的参数:

  der("x-forwarded-for") : 10.47.103.13,4.2.2.2,10.96.112.230

  der("X-Real-IP") : 10.47.103.13

  oteAddr():10.96.112.230

客户端访问经过转发,IP将会追加在其后并以逗号隔开。最终准确的客户端信息为:

x-forwarded-for 不为空,则为逗号前第一个IP ;

X-Real-IP不为空,则为该IP ;

否则为getRemoteAddr() ;

相关请求头的解释:

X-Forwarded-For :这是一个 Squid 开发的字段,只有在通过了HTTP代理或者负载均衡服务器时才会添加该项。    

    格式为X-Forwarded-For:client1,proxy1,proxy2,一般情况下,第一个ip为客户端真实ip,后面的为经过的代理服务器ip。现在大部

分的代理都会加上这个请求头。

Proxy-Client-IP/WL- Proxy-Client-IP :这个一般是经过apache http服务器的请求才会有,用apache http做代理时一般会加上Proxy-

Client-IP请求头,而WL-Proxy-Client-IP是他的weblogic插件加上的头。

HTTP_CLIENT_IP :有些代理服务器会加上此请求头。

X-Real-IP :nginx代理一般会加上此请求头。

1 /**

2 * 获取用户真实IP地址,不使用oteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,

3 * 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值

4 */

5 private String getIpAddr(HttpServletRequest request) {

6 String ip = der("x-forwarded-for");

7 n("x-forwarded-for ip: " + ip);

8 if (ip != null && () != 0 && !"unknown".equalsIgnoreCase(ip)) {

9 // 多次反向代理后会有多个ip值,第一个ip才是真实ip

10 if( f(",")!=-1 ){

11 ip = (",")[0];

12 }

13 }

14 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

15 ip = der("Proxy-Client-IP");

16 n("Proxy-Client-IP ip: " + ip);

17 } 18 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

19 ip = der("WL-Proxy-Client-IP");

20 n("WL-Proxy-Client-IP ip: " + ip);

21 }

22 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

23 ip = der("HTTP_CLIENT_IP");

24 n("HTTP_CLIENT_IP ip: " + ip);

25 }

26 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

27 ip = der("HTTP_X_FORWARDED_FOR");

28 n("HTTP_X_FORWARDED_FOR ip: " + ip);

29 }

30 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

31 ip = der("X-Real-IP");

32 n("X-Real-IP ip: " + ip);

33 }

34 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

35 ip = oteAddr();

36 n("getRemoteAddr ip: " + ip);

37 }

38 n("获取客户端ip: " + ip);

39 return ip;

40 }

1 import rvletRequest;

2

3 /**

4 * IP校验

5 */

6 public class IPUtils {

7

8 public static String getClientAddress(HttpServletRequest request) {

9 if (request == null) {

10 return "unknown";

11 }

12 String ip = der("x-forwarded-for");

13 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

14 ip = der("Proxy-Client-IP");

15 }

16 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

17 ip = der("X-Forwarded-For");

18 }

19 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

20 ip = der("WL-Proxy-Client-IP");

21 }

22 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

23 ip = der("X-Real-IP");

24 }

25

26 if (ip == null || () == 0 || "unknown".equalsIgnoreCase(ip)) {

27 ip = oteAddr();

28 }

29 return ("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;

30 }

31

32 }

1 public String getIpAddr(HttpServletRequest request){

2 String ipAddress = der("x-forwarded-for");

3 if(ipAddress == null || () == 0 || "unknown".equalsIgnoreCase(ipAddress)) {

4 ipAddress = der("Proxy-Client-IP");

5 }

6 if(ipAddress == null || () == 0 || "unknown".equalsIgnoreCase(ipAddress)) {

7 ipAddress = der("WL-Proxy-Client-IP");

8 }

9 if(ipAddress == null || () == 0 || "unknown".equalsIgnoreCase(ipAddress)) {

10 ipAddress = oteAddr();

11 if(("127.0.0.1") || ("0:0:0:0:0:0:0:1")){

12 //根据网卡取本机配置的IP

13 InetAddress inet=null;

14 try {

15 inet = alHost();

16 } catch (UnknownHostException e) {

17 tackTrace();

18 }

19 ipAddress= tAddress();

20 }

21 }

22 //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割

23 if(ipAddress!=null && ()>15){ //"***.***.***.***".length() = 15

24 if(f(",")>0){

25 ipAddress = ing(0,f(",")); 26 }

27 }

28 return ipAddress;

29 }

1 import edReader;

2 import tputStream;

3 import ption;

4 import treamReader;

5 import ortedEncodingException;

6 import LConnection;

7 import ;

8

9 /**

10 * 根据IP地址获取详细的地域信息 第一个方法是传入ip获取真实地址 最后一个方法是获取访问者真实ip 即使通过Nginx多层代理也可以获取

11 */

12 public class AddressUtils {

13

14 public static String getAddresses(String content, String encodingString) throws UnsupportedEncodingException {

15 // 这里调用pconline的接口

16 String urlStr = "/service/";

17 // 从取得IP所在的省市区信息

18 String returnStr = getResult(urlStr, content, encodingString);

19 if (returnStr != null) {

20 // 处理返回的省市区信息

21 n(returnStr);

22 String[] temp = (",");

23 if ( < 3) {

24 return "0";// 无效IP,局域网测试

25 }

26 String country = "";

27 String area = "";

28 String region = "";

29 String city = "";

30 String county = "";

31 String isp = "";

32 for (int i = 0; i < ; i++) {

33 switch (i) {

34 case 1:

35 country = (temp[i].split(":"))[2].replaceAll(""", "");

36 country = decodeUnicode(country);// 国家

37 break;

38 // case 3:

39 // area = (temp[i].split(":"))[1].replaceAll(""", "");

40 // area =decodeUnicode(area);//地区

41 // break;

42 case 5:

43 region = (temp[i].split(":"))[1].replaceAll(""", "");

44 region = decodeUnicode(region);// 省份

45 break;

46 case 7:

47 city = (temp[i].split(":"))[1].replaceAll(""", "");

48 city = decodeUnicode(city);// 市区

49 break;

50 case 9:

51 county = (temp[i].split(":"))[1].replaceAll(""", "");

52 county = decodeUnicode(county);// 地区

53 break;

54 case 11:

55 isp = (temp[i].split(":"))[1].replaceAll(""", "");

56 isp = decodeUnicode(isp);// ISP公司

57 break;

58 }

59 }

60 n(country + area + "=" + region + "=" + city + "=" + county + "=" + isp);

61 StringBuffer sb = new StringBuffer(country).append(region).append(city).append(county).append(" ")

62 .append(isp);

63 return ng();

64 }

65 return null;

66 }

67

68 /**

69 * @param urlStr 请求的地址

70 * @param content 请求的参数 格式为:name=xxx&pwd=xxx

71 * @param encoding 服务器端请求编码。如GBK,UTF-8等

72 * @return

73 */

74 private static String getResult(String urlStr, String content, String encoding) {

75 URL url = null;

76 HttpURLConnection connection = null;

77 try { 78 url = new URL(urlStr);

79 connection = (HttpURLConnection) nnection();// 新建连接实例

80 nectTimeout(3000);// 设置连接超时时间,单位毫秒

81 dTimeout(3000);// 设置读取数据超时时间,单位毫秒

82 utput(true);// 是否打开输出流 true|false

83 nput(true);// 是否打开输入流true|false

84 uestMethod("POST");// 提交方法POST|GET

85 Caches(false);// 是否缓存true|false

86 t();// 打开连接端口

87 DataOutputStream out = new DataOutputStream(putStream());// 打开输出流往对端服务器写数据

88 ytes(content);// 写数据(提交表单)

89 ();// 刷新

90 ();// 关闭输出流

91 // 往对端写完数据对端服务器返回数据,以BufferedReader流来读取

92 BufferedReader reader = new BufferedReader(new InputStreamReader(utStream(), encoding));

93 StringBuffer buffer = new StringBuffer();

94 String line = "";

95 while ((line = ne()) != null) {

96 (line);

97 }

98 ();

99 return ng();

100 } catch (IOException e) {

101 tackTrace();

102 } finally {

103 if (connection != null) {

104 nect();// 关闭连接

105 }

106 }

107 return null;

108 }

109

110 /**

111 * unicode 转换成 中文

112 */

113 public static String decodeUnicode(String theString) {

114 char aChar;

115 int len = ();

116 StringBuffer outBuffer = new StringBuffer(len);

117 for (int x = 0; x < len;) {

118 aChar = (x++);

119 if (aChar == '') {

120 aChar = (x++);

121 if (aChar == 'u') {

122 int value = 0;

123 for (int i = 0; i < 4; i++) {

124 aChar = (x++);

125 switch (aChar) {

126 case '0':

127 case '1':

128 case '2':

129 case '3':

130 case '4':

131 case '5':

132 case '6':

133 case '7':

134 case '8':

135 case '9':

136 value = (value << 4) + aChar - '0';

137 break;

138 case 'a':

139 case 'b':

140 case 'c':

141 case 'd':

142 case 'e':

143 case 'f':

144 value = (value << 4) + 10 + aChar - 'a';

145 break;

146 case 'A':

147 case 'B':

148 case 'C':

149 case 'D':

150 case 'E':

151 case 'F':

152 value = (value << 4) + 10 + aChar - 'A';

153 break;

154 default:

155 throw new IllegalArgumentException("Malformed encoding.");

156 }

157 }

158 ((char) value);

159 } else {

160 if (aChar == 't') {

161 aChar = 't';162 } else if (aChar == 'r') {163 aChar = 'r';164 } else if (aChar == 'n') {165 aChar = 'n';166 } else if (aChar == 'f') {167 aChar = 'f';168 }169 (aChar);170 }171 } else {172 (aChar);173 }174 }175 return ng();176 }177

178 // 测试179 public static void main(String[] args) {180 AddressUtils addressUtils = new AddressUtils();181

182 /**183 * 测试IP:111.121.72.101 中国贵州省贵阳市 电信184 */185 String ip = "111.121.72.101";186 String address = "";187 try {188 address = resses("ip=" + ip, "utf-8");189 } catch (UnsupportedEncodingException e) {190 tackTrace();191 } catch (Exception e) {192 tackTrace();193 }194 n(address);//中国贵州省贵阳市 电信195 }196 }

本文标签: 客户端请求代理获取数据