Nuxt 3 SSR下如何将客户端IP传递至后端?当前仅传服务器IP
在Nuxt 3 SSR模式下传递客户端IP至后端的解决方案
问题现状
在Nuxt 3 SSR模式下调用外部API时,后端收到的是项目所在服务器的IP,而非客户端真实IP。仅将初始化插件重命名为geo.client.ts(客户端执行)时,才能正确传递客户端IP,但这会失去SSR初始化数据的能力。
解决方案
方案1:通过代理层转发客户端IP(推荐SSR场景使用)
这个方案可以在SSR阶段就将客户端IP传递给后端,同时保留SSR初始化的优势。
步骤1:修改代理层,添加客户端IP转发逻辑
更新server/api/[...].ts,从请求事件中提取客户端IP,并添加到转发给后端的请求头中:
import { joinURL } from 'ufo'; import { defineEventHandler, getRequestHeader, setRequestHeader } from 'h3'; export default defineEventHandler((event) => { const config = useRuntimeConfig(); // 获取客户端真实IP,优先取反向代理传递的头,再取原生连接IP const clientIp = getRequestHeader(event, 'x-forwarded-for') || getRequestHeader(event, 'x-real-ip') || event.node.req.socket.remoteAddress; // 将客户端IP注入到转发请求的头里 if (clientIp) { setRequestHeader(event, 'X-Forwarded-For', clientIp); setRequestHeader(event, 'X-Real-IP', clientIp); } return proxyRequest(event, joinURL(config.public.API_BASE_URL, event.path)); });
步骤2:调整插件的请求路径为代理地址
修改geo.ts中的useFetch调用,去掉直接指向外部API的baseURL,改用Nuxt的代理接口路径:
import { useGeoStore } from '~/store/geo'; export default defineNuxtPlugin(async () => { const geoStore = useGeoStore(); const { data: geo } = await useFetch('/api/v1/session', { headers: useRequestHeaders(['cookie']), watch: false }); });
原理说明
- SSR阶段插件在服务器端执行,请求先发送到Nuxt代理接口
/api/v1/session - 代理层从原始请求中提取客户端IP,将其注入到转发给后端API的请求头
- 后端API可通过
X-Forwarded-For或X-Real-IP头获取客户端真实IP
方案2:保持客户端执行(无需SSR初始化场景)
如果不需要在页面首次渲染时就完成会话和地理位置初始化,直接将插件命名为geo.client.ts即可。此时请求从客户端浏览器发起,后端会直接获取到客户端IP,但页面首次加载时可能出现数据未就绪的状态。
补充提示
- 若Nuxt部署在反向代理(如Nginx、Cloudflare)之后,需确保反向代理已正确配置,将
X-Forwarded-For和X-Real-IP头传递给Nuxt服务器 - 全局fetch配置中,若在SSR阶段使用,同样需要通过代理接口发起请求,才能带上客户端IP
内容的提问来源于stack exchange,提问作者Ruslan
相关产品推荐
相关产品推荐

