基于nginx反向代理获取用户真实Ip地址详解

目录
  • 引言
  • 1.修改Nginx配置:
  • 2.java获取客户端Ip
  • 附:一个ip工具类
  • 总结

引言

nginx做反向代理时,默认的配置后端获取到的Ip地址都来自于nginx,用request.getRemoteAddr();获取到的是nginx的ip地址,而不是用户的真实ip.

1.修改Nginx配置:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

server {

listen 80;

server_name jenkins.local.com;

location / {

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_pass http://192.168.10.204:8899;

}

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

index index.html index.htm index.jsp index.action default.html;

}

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

在原来的基础配置上加上后三行配置,就可以使用request.getHeader(“x-forwarded-for”)来获取用户真实的Ip地址了

2.java获取客户端Ip

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

package com.zimax.cqyf.admin.util;

import javax.servlet.http.HttpServletRequest;

import java.net.InetAddress;

import java.net.UnknownHostException;

/**

* http工具类

*/

public class HttpUtils {

/**

* 获取真实的ip

* @param request

* @return

* @throws UnknownHostException

*/

public static String getRealIp(HttpServletRequest request){

String ip;

// 有的user可能使用代理,为处理用户使用代理的情况,使用x-forwarded-for

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

ip = request.getRemoteAddr();

} else {

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

}

if ("127.0.0.1".equals(ip)) {

try {

// 获取本机真正的ip地址

ip = InetAddress.getLocalHost().getHostAddress();

}catch (Exception e){

e.printStackTrace();

}

}

return ip;

}

}

附:一个ip工具类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

import javax.servlet.http.HttpServletRequest;

/**

* IP地址工具类

* @author xudongdong

*

*/

public class IpUtil {

/**

* 私有化构造器

*/

private IpUtil() {

}

/**

* 获取真实IP地址

* <p>使用getRealIP代替该方法</p>

* @param request req

* @return ip

*/

@Deprecated

public static String getClinetIpByReq(HttpServletRequest request) {

// 获取客户端ip地址

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

if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {

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

}

if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {

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

}

if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {

clientIp = request.getRemoteAddr();

}

/*

* 对于获取到多ip的情况下,找到公网ip.

*/

String sIP = null;

if (clientIp != null && !clientIp.contains("unknown") && clientIp.indexOf(",") > 0) {

String[] ipsz = clientIp.split(",");

for (String anIpsz : ipsz) {

if (!isInnerIP(anIpsz.trim())) {

sIP = anIpsz.trim();

break;

}

}

/*

* 如果多ip都是内网ip,则取第一个ip.

*/

if (null == sIP) {

sIP = ipsz[0].trim();

}

clientIp = sIP;

}

if (clientIp != null && clientIp.contains("unknown")){

clientIp =clientIp.replaceAll("unknown,", "");

clientIp = clientIp.trim();

}

if ("".equals(clientIp) || null == clientIp){

clientIp = "127.0.0.1";

}

return clientIp;

}

/**

* 判断IP是否是内网地址

* @param ipAddress ip地址

* @return 是否是内网地址

*/

public static boolean isInnerIP(String ipAddress) {

boolean isInnerIp;

long ipNum = getIpNum(ipAddress);

/**

私有IP:A类 10.0.0.0-10.255.255.255

B类 172.16.0.0-172.31.255.255

C类 192.168.0.0-192.168.255.255

当然,还有127这个网段是环回地址

**/

long aBegin = getIpNum("10.0.0.0");

long aEnd = getIpNum("10.255.255.255");

long bBegin = getIpNum("172.16.0.0");

long bEnd = getIpNum("172.31.255.255");

long cBegin = getIpNum("192.168.0.0");

long cEnd = getIpNum("192.168.255.255");

isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd)

|| ipAddress.equals("127.0.0.1");

return isInnerIp;

}

private static long getIpNum(String ipAddress) {

String[] ip = ipAddress.split("\\.");

long a = Integer.parseInt(ip[0]);

long b = Integer.parseInt(ip[1]);

long c = Integer.parseInt(ip[2]);

long d = Integer.parseInt(ip[3]);

return a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;

}

private static boolean isInner(long userIp, long begin, long end) {

return (userIp >= begin) && (userIp <= end);

}

public static String getRealIP(HttpServletRequest request){

// 获取客户端ip地址

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

if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {

clientIp = request.getRemoteAddr();

}

String[] clientIps = clientIp.split(",");

if(clientIps.length <= 1) return clientIp.trim();

// 判断是否来自CDN

if(isComefromCDN(request)){

if(clientIps.length>=2) return clientIps[clientIps.length-2].trim();

}

return clientIps[clientIps.length-1].trim();

}

private static boolean isComefromCDN(HttpServletRequest request) {

String host = request.getHeader("host");

return host.contains("www.189.cn") ||host.contains("shouji.189.cn") || host.contains(

"image2.chinatelecom-ec.com") || host.contains(

"image1.chinatelecom-ec.com");

}

}

总结

到此这篇关于基于nginx反向代理获取用户真实Ip地址的文章就介绍到这了,更多相关nginx获取用户真实Ip内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/sll714827/article/details/123332269

本文链接:https://my.lmcjl.com/post/5276.html

展开阅读全文

4 评论

留下您的评论.