Nginx反向代理场景下Node.js后端如何正确获取客户端真实IP?
现有配置有效性说明
你当前的Nginx配置(已引入包含X-Real-IP、X-Forwarded-For的proxy_params)、Express的app.set('trust proxy', true)设置已经符合获取客户端真实IP的要求,只要你的EC2实例没有额外前置未配置的七层代理(比如Cloudflare、AWS ALB等),同时Node服务的3001端口没有直接对外暴露公网,这套配置可以稳定返回客户端真实IP。
业务接口中获取IP的调用方法
不需要再使用public-ip类的npm包,这类包的作用是获取当前Node服务所在服务器的公网出口IP,和访问用户的IP无关。
你已经开启了Express的trust proxy配置,优先使用Express内置的req.ip属性即可,框架会自动解析代理头、过滤代理层IP,比手动读头更稳妥,业务代码示例如下:
// 示例接口:记录用户操作的客户端IP到数据库 app.post('/api/user/operate', async (req, res) => { // 直接获取解析完成的真实客户端IP const clientIp = req.ip // 也可以兼容手动解析的写法,注意X-Forwarded-For是逗号分隔的IP列表,第一个为真实用户IP // const clientIp = req.headers['x-forwarded-for']?.split(',')[0].trim() || req.connection.remoteAddress // 后续业务逻辑:写入数据库 await UserOperateLog.create({ userId: req.body.userId, operateIp: clientIp, operateTime: new Date(), operateContent: req.body.content }) res.json({code: 0, msg: '操作成功'}) })
优化建议
- 优先使用Express内置的
req.ip属性,不要手动解析x-forwarded-for头:如果经过多层代理,x-forwarded-for的格式为客户端IP, 代理1IP, 代理2IP...,手动解析容易取错位置,Express开了trust proxy之后会自动识别可信代理,直接返回真实用户IP。 - 如果后续EC2前新增CDN、负载均衡等其他七层代理,需要把这些代理的IP段添加到Express的
trust proxy配置里,比如配置app.set('trust proxy', 2)表示信任前两层代理,或者明确指定可信IP段app.set('trust proxy', ['127.0.0.1', '负载均衡IP段']),避免伪造IP风险。 - 确保EC2安全组、服务器防火墙的3001端口仅允许本地127.0.0.1访问,不要对外公网放开,避免攻击者直接访问Node服务伪造请求头篡改IP。
- 可额外校验Nginx传递的
X-Real-IP和req.ip的取值是否一致,进一步降低IP伪造风险。
内容的提问来源于stack exchange,提问作者Aks
相关产品推荐
相关产品推荐

