问题
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的
解决方案
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 -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;
}
其他