nginx反向代理服务器时 获取用户IP的几种方法

最近刚刚写好个人电商网站,然后忙于找工作,可是自己的网站我想看到访问人数与访问的ip地址。这样可以了解是否有人看到。

最开始的时候查了一下资料,也没有去想其他的问题,直接就开始写代码了,可是发现写好之后,我在本机进行测试,获取到的ip地址都是127.0.0.1,这是有点疑惑,为什么会出现这种问题。我的代码是这样的。

public String addOrUpdate(HttpServletRequest request){
        String ip = request.getRemoteAddr();
        return ip;
    }

网上查了之后说是我这里使用了代理软件,所以只能获取到本地localhost地址,只能是127.0.0.1

然后 网上给出了两种解决办法

  • 方法一
public String getRemortIP(HttpServletRequest request) {  
    if (request.getHeader("x-forwarded-for") == null) {  
        return request.getRemoteAddr();  
    }  
    return request.getHeader("x-forwarded-for");  
}  
  • 方法二
public String getIpAddr(HttpServletRequest request) {  
    String ip = request.getHeader("x-forwarded-for");  
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
        ip = request.getHeader("Proxy-Client-IP");  
    }  
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
        ip = request.getHeader("WL-Proxy-Client-IP");  
    }  
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
        ip = request.getRemoteAddr();  
    }  
    return ip;  
}  

可是经过我的测试两种方法都不管用,不知道是出于什么原因,这时候我在想可能原因在于我使用的nginx设置上面,这个还真在网上找到了答案

  • nginx配置这里需要添加这样一条
location /{
           root   html;
           index  index.html index.htm;
           proxy_pass                  http://backend; 
           proxy_redirect              off;
           proxy_set_header            Host $host;
           proxy_set_header            X-real-ip $remote_addr;
           proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
        }
  • 然后修改Java代码
String ip = request.getHeader("X-Real-IP");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
  • 这样就可以获取到真实的ip地址了

网上查到给出的解释是这样的

我在查阅资料时,有一本名叫《实战nginx》的书,作者张晏,这本书上有这么一段话“经过反向代理后,由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是反向代理服务器的ip地址”。这句话的意思是说,当你使用了nginx反向服务器后,在web端使用request.getRemoteAddr()(本质上就是获取$remote_addr),取得的是nginx的地址,即$remote_addr变量中封装的是nginx的地址,当然是没法获得用户的真实ip的,但是,nginx是可以获得用户的真实ip的,也就是说nginx使用$remote_addr变量时获得的是用户的真实ip,如果我们想要在web端获得用户的真实ip,就必须在nginx这里作一个赋值操作,如下:

proxy_set_header X-real-ip $remote_addr;

其中这个X-real-ip是一个自定义的变量名,名字可以随意取,这样做完之后,用户的真实ip就被放在X-real-ip这个变量里了,然后,在web端可以这样获取:

request.getAttribute("X-real-ip")

这样就明白了吧。

标签:代理服务器Nginx 发布于:2019-11-12 23:50:37