nginx代理获取真实ip

function getClientIp(req) {
    let api = req.connection.remoteAddress || req.socket.remoteAddress || (req.connection.socket ? req.connection.socket.remoteAddress : null) || req.headers['x-forwarded-for']; // x-forwarded-for容易被伪造
    if (api.indexOf('::ffff:') !== -1) {
        api = api.substring(7);
    }
    return api;
}

使用上面的代码,获取到的客户端的ip一直是::ffff:127.0.0.1,得不到正确的ip
原因是服务端使用了nginx进行端口转发,如果没使用nginx进行代理,getClientIp函数是可以正确获取到公网ip的
解决方案
修改nginx配置

server {
        listen 80;
        server_name www.xxx.com xxx.com;
        location / {
            proxy_pass http://127.0.0.1:8080;
            proxy_set_header x-real-ip $remote_addr;
            proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
            proxy_set_header host $http_host;
        }
}

重启nginx

nginx -s reload

修改函数

function getClientIp(req, proxyType) {
    let ip = req.connection.remoteAddress || req.socket.remoteAddress || (req.connection.socket ? req.connection.socket.remoteAddress : null);
    // 如果使用了nginx代理
    if (proxyType === 'nginx') {
        // headers上的信息容易被伪造,但是我不care,自有办法过滤,例如'x-nginx-proxy'和'x-real-ip'我在nginx配置里做了一层拦截把他们设置成了'true'和真实ip,所以不用担心被伪造
        // 如果没用代理的话,我直接通过req.connection.remoteAddress获取到的也是真实ip,所以我不care
        ip = req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || ip;
    }
    const ipArr = ip.split(',');
    // 如果使用了nginx代理,如果没配置'x-real-ip'只配置了'x-forwarded-for'为$proxy_add_x_forwarded_for,如果客户端也设置了'x-forwarded-for'进行伪造ip
    // 则req.headers['x-forwarded-for']的格式为ip1,ip2只有最后一个才是真实的ip
    if (proxyType === 'nginx') {
        ip = ipArr[ipArr.length - 1];
    }
    if (ip.indexOf('::ffff:') !== -1) {
        ip = ip.substring(7);
    }
    return ip;
}
发布了55 篇原创文章 · 获赞 12 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/mrzhangdulin/article/details/103726342