我不完全明白我应该如何获得一个远程用户IP地址。
假设我有一个简单的请求路由,如:
app.get(/, function (req, res){
var forwardedIpsStr = req.header('x-forwarded-for');
var IP = '';
if (forwardedIpsStr) {
IP = forwardedIps = forwardedIpsStr.split(',')[0];
}
});
上面的方法是否正确,以获得真实的用户IP地址或有更好的方法?
那么代理呢?
特别是对于node, http server组件的文档,在事件连接下说:
建立新的TCP流时触发。套接字是类型对象
net.Socket。通常用户不会想要访问这个事件。在
特别是,套接字将不会发出可读的事件,因为如何
协议解析器附加到套接字。插座也可以
通过request.connection访问。
这意味着请求。连接是一个套接字,根据文档,确实有一个套接字。根据文档,remoteAddress属性为:
远程IP地址的字符串表示形式。例如,
'74.125.127.100'或'2001:4860:a005::68'。
在express下,请求对象也是Node http请求对象的一个实例,因此这种方法仍然有效。
然而,在Express.js下,请求已经有两个属性:req。IP和req.ips
req.ip
返回远程地址,或者当启用“信任代理”时返回上游地址。
req.ips
当“trust proxy”为true时,解析“X-Forwarded-For”ip地址列表并返回一个数组,否则为空数组
返回。例如,如果值是“client, proxy1, proxy2”
将接收数组["client", "proxy1", "proxy2"],其中"proxy2"
是下游最远的地方。
值得一提的是,根据我的理解,特快要求。IP是比req.connection更好的方法。remoteAddress, since req。ip包含实际的客户端ip(前提是在express中启用了可信代理),而另一个可能包含代理的ip地址(如果有的话)。
这就是为什么目前公认的答案是:
Var IP = req。标题(“x-forwarded-for”)| |
req.connection.remoteAddress;
要求的事情。Headers ['x-forwarded-for']将等价于express req.ip。
如果你很好使用第三方库。可以检查request-ip。
你可以用is by
import requestIp from 'request-ip';
app.use(requestIp.mw())
app.use((req, res) => {
const ip = req.clientIp;
});
源代码很长,所以我就不复制了,你可以在https://github.com/pbojinov/request-ip/blob/master/src/index.js上查看
基本上,
It looks for specific headers in the request and falls back to some
defaults if they do not exist.
The user ip is determined by the following order:
X-Client-IP
X-Forwarded-For (Header may return multiple IP addresses in the format: "client IP, proxy 1 IP, proxy 2 IP", so we take the the first
one.)
CF-Connecting-IP (Cloudflare)
Fastly-Client-Ip (Fastly CDN and Firebase hosting header when forwared to a cloud function)
True-Client-Ip (Akamai and Cloudflare)
X-Real-IP (Nginx proxy/FastCGI)
X-Cluster-Client-IP (Rackspace LB, Riverbed Stingray)
X-Forwarded, Forwarded-For and Forwarded (Variations of #2)
req.connection.remoteAddress
req.socket.remoteAddress
req.connection.socket.remoteAddress
req.info.remoteAddress
If an IP address cannot be found, it will return null.
公开:我和图书馆没有关系。
将所有的witk @kakopappa解决方案加上morgan客户端ip地址的日志记录:
morgan.token('client_ip', function getId(req) {
return req.client_ip
});
const LOG_OUT = ':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" :client_ip'
self.app.use(morgan(LOG_OUT, {
skip: function(req, res) { // custom logging: filter status codes
return res.statusCode < self._options.logging.statusCode;
}
}));
// could-flare, nginx and x-real-ip support
var getIpInfoMiddleware = function(req, res, next) {
var client_ip;
if (req.headers['cf-connecting-ip'] && req.headers['cf-connecting-ip'].split(', ').length) {
var first = req.headers['cf-connecting-ip'].split(', ');
client_ip = first[0];
} else {
client_ip = req.headers['x-forwarded-for'] || req.headers['x-real-ip'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
}
req.client_ip = client_ip;
next();
};
self.app.use(getIpInfoMiddleware);