我不完全明白我应该如何获得一个远程用户IP地址。
假设我有一个简单的请求路由,如:
app.get(/, function (req, res){
var forwardedIpsStr = req.header('x-forwarded-for');
var IP = '';
if (forwardedIpsStr) {
IP = forwardedIps = forwardedIpsStr.split(',')[0];
}
});
上面的方法是否正确,以获得真实的用户IP地址或有更好的方法?
那么代理呢?
虽然来自@alessioalex的答案是有效的,但在Express - guide的Express后台代理部分中有另一种方法。
在初始化代码中添加app.set('trust proxy', true)。
当您想要获取远程客户端的ip时,使用req。IP或req。以通常的方式进行Ips(就好像没有反向代理一样)
可选的阅读:
Use req.ip or req.ips. req.connection.remoteAddress does't work with this solution.
More options for 'trust proxy' are available if you need something more sophisticated than trusting everything passed through in x-forwarded-for header (for example, when your proxy doesn't remove preexisting x-forwarded-for header from untrusted sources). See the linked guide for more details.
If your proxy server does not populated x-forwarded-for header, there are two possibilities.
The proxy server does not relay the information on where the request was originally. In this case, there would be no way to find out where the request was originally from. You need to modify configuration of the proxy server first.
For example, if you use nginx as your reverse proxy, you may need to add proxy_set_header X-Forwarded-For $remote_addr; to your configuration.
The proxy server relays the information on where the request was originally from in a proprietary fashion (for example, custom http header). In such case, this answer would not work. There may be a custom way to get that information out, but you need to first understand the mechanism.
特别是对于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。
这只是这个答案的附加信息。
如果你正在使用nginx,你需要添加proxy_set_header X-Real-IP $remote_addr;到站点的位置块。例如:/etc/nginx/sites-available/www.example.com。下面是一个服务器块示例。
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.1.1:3080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
重新启动nginx后,你将能够使用req访问你的节点/express应用程序路由中的ip。headers['x-real-ip'] || req.connection.remoteAddress;
将所有的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);
如果你很好使用第三方库。可以检查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.
公开:我和图书馆没有关系。