美文网首页
ip ::ffff:127.0.0.1

ip ::ffff:127.0.0.1

作者: 一位有礼貌的先生 | 来源:发表于2018-01-30 13:33 被阅读0次

问题

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;
}

其他

相关文章

网友评论

      本文标题:ip ::ffff:127.0.0.1

      本文链接:https://www.haomeiwen.com/subject/vtqczxtx.html