You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cloud Run服务无法获取客户端真实IP地址问题排查

问题:Cloud Run上Socket.io获取客户端IP始终显示美国地址

我在Google Cloud Run上部署了一个使用Socket.io的服务。当Socket客户端连接时,我通过如下函数从socket.handshake中提取x-forwarded-for作为客户端IP,并调用GeoPlugin接口查询地理位置。但无论用户所在位置如何,IP始终解析为美国地址。该服务已通过域名映射绑定自定义域名,且相同服务部署在Heroku时可正常获取客户端真实IP。我的Cloud Run服务均部署在us-central1区域,请问此问题的原因是什么?

函数代码:

async getSocketIP(socket) {
    let { headers, address } = socket.handshake;
    let { origin } = headers;
    let ip = headers['x-forwarded-for'];
    let userAgent = headers['user-agent'];
    try {
        let locationPointUrl = `http://www.geoplugin.net/json.gp?ip=${ip}`;
        let { data: location } = await axios.get(locationPointUrl);
    } catch (e) {
        console.log(`Error get client online IP on Socket IO`);
    }
}

原因分析

  • 多层转发的x-forwarded-for头部:Cloud Run依赖全球负载均衡,当请求通过自定义域名到达服务时,x-forwarded-for头部会以逗号分隔的形式包含多个IP(格式为客户端真实IP, 负载均衡节点IP, ...)。你直接读取整个头部值,拿到的是列表中靠后的负载均衡节点IP(该节点部署在us-central1区域,所以解析为美国地址)。
  • Socket.io未配置信任代理:默认情况下Socket.io不会信任代理转发的头部,无法正确识别真实的客户端IP来源。

解决方案

1. 正确解析x-forwarded-for头部

拆分逗号分隔的IP列表,取第一个值作为客户端真实IP:

async getSocketIP(socket) {
    let { headers } = socket.handshake;
    let ip = headers['x-forwarded-for'];
    // 提取列表中的第一个IP(客户端真实IP)
    if (ip) {
        ip = ip.split(',').shift().trim();
    }
    let userAgent = headers['user-agent'];
    try {
        let locationPointUrl = `http://www.geoplugin.net/json.gp?ip=${ip}`;
        let { data: location } = await axios.get(locationPointUrl);
        // 处理地理位置数据
    } catch (e) {
        console.log(`Error get client online IP on Socket IO`, e);
    }
}

2. 配置Socket.io信任代理

在Socket.io服务端初始化时开启trustProxy选项,确保它正确处理代理转发的头部:

const io = require('socket.io')(server, {
    cors: {
        origin: "*", // 根据你的业务需求调整允许的源
        methods: ["GET", "POST"]
    },
    trustProxy: true // 关键:信任代理服务器,让Socket.io识别转发的客户端IP
});

内容的提问来源于stack exchange,提问作者ololo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:15:07