如何在Next.js的getServerSideProps方法中正确获取客户端IP
问题根因
你调用基础IP查询方法拿到的是服务器自身/反向代理节点的IP,原因是生产环境下Next.js服务通常不会直接暴露在公网,用户请求会经过CDN、反向代理层转发后才到达Next.js服务,直接从TCP连接中读取的IP是最近一层代理节点的地址,并非真实客户端IP。
正确获取方案
1. 先获取请求上下文的req对象
getServerSideProps的入参context中自带原生Node.js的请求对象req,所有客户端请求头都可以从这个对象中读取:
export async function getServerSideProps(context) { const { req } = context; // IP获取逻辑写在这里 }
2. 按优先级读取IP相关请求头
不同部署环境会自动注入对应的客户端IP请求头,你可以按优先级依次读取,最通用的字段是x-forwarded-for,这个字段的值是逗号分隔的IP列表,最左侧的就是原始客户端IP:
- 通用标准头:
x-forwarded-for - Cloudflare部署专用头:
cf-connecting-ip - Vercel部署专用头:
x-real-ip、x-vercel-forwarded-for - 自定义Nginx代理头:
x-real-ip
3. 完整实现代码
export async function getServerSideProps(context) { const { req } = context; let clientIp = ""; // 按优先级读取IP const forwardFor = req.headers["x-forwarded-for"]; if (forwardFor) { clientIp = Array.isArray(forwardFor) ? forwardFor[0] : forwardFor.split(",")[0].trim(); } else if (req.headers["cf-connecting-ip"]) { clientIp = req.headers["cf-connecting-ip"]; } else if (req.headers["x-real-ip"]) { clientIp = req.headers["x-real-ip"]; } else { // 兜底逻辑,本地开发/无代理场景可用 clientIp = req.socket.remoteAddress; } // 可将IP传递给前端页面组件 return { props: { clientIp } } }
注意事项
- 本地开发环境测试时拿到的是
::1(IPv6本地回环)或者127.0.0.1,属于正常情况,部署到线上公网环境后会返回真实客户端IP - 如果你自行使用Nginx做反向代理,需要在Nginx配置中添加头转发规则,否则无法读取到对应IP头:
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
- 不要在客户端侧调用公开IP查询接口再将结果传给服务端,这种方式容易被伪造,只有在服务端直接从请求上下文读取的IP才是可信的。
内容的提问来源于stack exchange,提问作者Archana Agivale
相关产品推荐
相关产品推荐

