开发时遇到了这么一个问题:无论如何都获取不到接口中传过来请求的ip地址,一直都是127.0.0.1,由于是分模块开发,后台的请求均能获取到ip。

{"code":200,"message":"操作成功","data":"127.0.0.1"}

于是开始排查,最先觉得是Request没有按照预想的情况那样存在ThreadLocal中

public class RequestHolder {
    private final static ThreadLocal<Object> requestHolder = new ThreadLocal<>();

    public static void add(Object object) {
        requestHolder.set(object);
    }

    public static Object get(){
        return requestHolder.get();
    }

    public static void remove() {
        requestHolder.remove();
    }
}

因为IP工具类是从这拿Request的

    public static String getIP() {
        return getIpAddr(getRequest());
    }
    
    private static HttpServletRequest getRequest() {
        return (HttpServletRequest) RequestHolder.get();
    }

几经修改后仍然无解,怀疑是拦截器和过滤器的问题,于是将配置改到近乎与后台的相同,仍然无解!

最后想到,为什么本地调试就能获取到ip,部署到服务器就不行?后才恍然大悟,为了能让后台与前台公用一个域名,我使用Nginx代理了二级目录给前台接口

    location /api {
        proxy_pass http://127.0.0.1:8101/api;
    }

当初配置时以为只需写proxy_pass即可,实际上还需将ip信息一同转发,才能满足业务需求

    location /api {
        proxy_pass http://127.0.0.1:8101/api;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

获取成功

{"code":200,"message":"操作成功","data":"140.240.96.x"}