Java如何获取使用nginx做负载之后的真实IP
本文由 小茗同学 发表于 2016-08-25 浏览(7010)
最后修改 2016-08-25 标签:nginx 获取 真实 ip java

分析

由于用户直接访问的是nginx,nginx再来访问我们的java后台,假如nginx和tomcat都在同一台服务器的话,默认情况下使用request.getRemoteAddr()获取肯定是127.0.0.1,所以无法获取用户的真实IP。

那么如何才能获取真实IP呢,方法很简单,nginx在收到客户端直接请求时将客户端的IP保存起来,并在请求真正后台时将真实IP放到header中去,然后Java获取这个头部即可。

nginx增加配置

具体放到什么头部去呢?肯定什么头部都可以,但是呢,大家都有个不成文的习惯,就是放到X-Real-IPX-Forwarded-For,二者貌似有点区别:前者一般只存放最后一次代理IP,后者则将所有代理IP逗号拼接起来,不过一般情况下也不可能用那么多次代理,所以也懒得管这细节啦,具体nginx配置如下:

server {
    listen       80;
    server_name  localhost liuxianan.com;
    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        root   html;
        index  index.html;
    }
}

Java获取真实IP

/**
 * 获取客户端IP,支持反向代理,如nginx,但不支持正向代理,比如客户端浏览器自己使用代理工具
 * @param request
 * @return 客户端IP
 */
public static String getClientIP(HttpServletRequest request)
{
    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();
    return ip;
}