引言nginx做反向代理时,默认的配置后端获取到的ip地址都来自于nginx,用request.getremoteaddr();获取到的是nginx的ip地址,而不是用户的真实ip.
1.修改nginx配置: 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获取客户端ippackage 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工具类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地址的详细内容。