在Node.js的request对象里,客户端的IP地址可能会存在多个不同的地方,比如,可能在HTTP header的x-forwarded-for
,或者其他的一些地方如request.connection
, request.socket
, request.info
, 或者request.raw
。
自己写代码,这不是一个复杂的事情,但是还是尽量避免自己去重复造轮子。NPM仓库里有一些针对的模块,比如@supercharge/request-ip这个库。这个库会检查一些可能出现IP地址的地方,然后返回找到的IP地址。
如果使用这个库呢?
第一步,把这个库当做自己项目的一个依赖:
npm i @supercharge/request-ip
第二步,用这样的方式从request对象里获得IP地址:
const RequestIp = require('@supercharge/request-ip') const ip = RequestIp.getClientIp(request) // 比如 '127.0.0.1' 是一个IP V4地址 // '2001:0db8:85a3:0000:0000:8a2e:0370:7334' 是一个IP v6地址 // 如果没有找到IP地址,会返回一个undefined。
就是这样:把request
对象传入RequestIp.getClientIp(request)
,就可以拿到结果了。通常情况下,在web的request对象里应该是能够拿到一个IP地址的,除非代码运行的方式不正确。
在其他的Web框架里检测IP地址,比如Express/hapi/Fastify/Koa等。
不同的框架用法不一样,有些是在中间件里,有些事在路由handler里面。
比如在Express的中间件里:
const RequestIp = require('@supercharge/request-ip'); const expressMiddleware = function (req, res, next) { req.ip = RequestIp.getClientIp(req); next(); }
在Hapi的路由handler里:
const Hapi = require('@hapi/hapi'); const RequestIp = require('@supercharge/request-ip'); const server = new Hapi.Server({ host: 'localhost' }); server.route({ method: 'GET', path: '/login', handler: (request, h) => { const ip = RequestIp.getClientIp(request); return h.response(ip); } });
是不是很简单呢?