Nginx反向代理后获取的IP是127.0.0.1

我的服务是通过java写的,当然获取方式也是通过java来获取,当然其他服务获取的原理是一样的 都是从header头中获取这个ip

如果想看源代码的实际运用,可以移步到本博客的开源代码中去查看,在AccessStatisticInterceptor中会打印一下当前访问的远程ip是谁,最核心的原理,也就是从头信息中获取x-forwarded-for这个key

 

首先是nginx的配置

  server {
    listen 80;
    server_name www.4klike.com;
    location / {
      proxy_pass http://4klike_01;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    error_page 404 =https://www.4klike.com/404;
  }

需要介绍一下 上面的是我从我自己的服务器中摘除来一部分,可以看到在通用的配置中,群在几个key,我们一个个的介绍

proxy_pass 这个是说你的服务路由到哪个ip及端口上去因为我配置了upstream,所以这里只需要写一下别名就可以

proxy_set_header用来设定被代理服务器接收到的header信息,

再讲讲proxy_set_header后面的几个key

 

X-Real-IP 是指客户端的真实IP,如果设置了$remote_addr这个值,后端服务器就能获取到客户端的真实IP,也就是此例中的192.168.1.1

Host host的值设置为$proxyhost,是指proxy_pass中设置的host值,也就是192.168.1.3,也就是服务器的IP地址。

X-Forwarded-For 这个变量的值有$proxy_add_x_forwarded_for和$remote_addr,在只有一个代理服务器的转发的情况下,两者的效果貌似差不多,都可以真实的显示出客户端原始ip。

 

nginx配置完后,需要重启才可以生效,但是问题来了,在实际服务中获取的getRemoteAddr()还是127.0.0.1 为啥呢? 原因是你将远程地址放到header头中了,当然获取的时候 也需要从header头中来获取,我这里只写了java的代码,php及其他高级语言也可以从header中直接获取

 

public static String getIP(HttpServletRequest request){
    String ip = request.getHeader("X-Forwarded-For");
    System.out.println("x-forwarded-for ip: " + ip);
    if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
        // 多次反向代理后会有多个ip值,第一个ip才是真实ip
        if(ip.contains(",")){
            ip = ip.split(",")[0];
        }
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
        System.out.println("Proxy-Client-IP ip: " + ip);
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("WL-Proxy-Client-IP");
        System.out.println("WL-Proxy-Client-IP ip: " + ip);
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("HTTP_CLIENT_IP");
        System.out.println("HTTP_CLIENT_IP ip: " + ip);
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        System.out.println("HTTP_X_FORWARDED_FOR ip: " + ip);
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("X-Real-IP");
        System.out.println("X-Real-IP ip: " + ip);
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getRemoteAddr();
        System.out.println("getRemoteAddr ip: " + ip);
    }
    System.out.println("获取客户端ip: " + ip);
    return ip;
}

 

能从代码中看到我从header中获取了一下,正式ng中配置的x-forwarded-for,当然如果你愿意,ng的配置和这里的配置随你的开心,名字自己定义,但是必须保证这两个地方的名称是一致的,希望这篇文章能帮到您 smileysmileysmiley

 

 

 

您还没有登录,请先 登录或者 注册后,添加评论