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

.NET Core Web API如何获取客户端真实IP地址?

这个问题我之前也碰到过!你看到的::1和::ffff:127.0.0.1其实是本地回环地址(测试场景)或者反向代理服务器的地址,并不是真实客户端的IP。核心原因是:当你的API部署在反向代理(比如Nginx、IIS、Azure App Service)后面时,RemoteIpAddress默认会抓取代理服务器的IP,而非用户的真实IP。下面是具体的解决步骤:

解决方法

1. 配置转发头中间件(关键步骤)

ASP.NET Core需要明确信任反向代理发送的转发头(比如X-Forwarded-For),才能正确解析真实客户端IP。在Program.cs中添加以下配置:

首先注册转发头选项:

builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    // 启用转发X-Forwarded-For(客户端IP)和X-Forwarded-Proto(请求协议)
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    
    // 添加已知的代理IP到信任列表(根据你的部署环境调整,这里先加本地测试的回环地址)
    options.KnownProxies.Add(IPAddress.Parse("127.0.0.1"));
    options.KnownProxies.Add(IPAddress.Parse("::1"));
    
    // 如果是云服务(比如Azure),可以用KnownNetworks信任整个代理网段,避免逐个添加IP
    // options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 8));
});

然后在管道中启用转发头中间件(注意必须放在UseRouting之前):

// 必须在UseRouting之前调用,确保转发头先被解析
app.UseForwardedHeaders();

app.UseRouting();
// ...其他中间件配置

2. 编写辅助方法获取真实IP

即使配置了转发头,最好直接解析X-Forwarded-For头(因为请求可能经过多层代理)——这个头的值是逗号分隔的IP列表,第一个IP就是最原始的客户端IP。可以写一个复用的辅助方法:

private string GetRealClientIp(HttpContext context)
{
    // 优先从X-Forwarded-For头获取真实IP
    var forwardedForHeader = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
    if (!string.IsNullOrWhiteSpace(forwardedForHeader))
    {
        // 拆分多个IP,取第一个(最原始的客户端IP)
        var ipAddresses = forwardedForHeader.Split(',', StringSplitOptions.RemoveEmptyEntries);
        return ipAddresses.First().Trim();
    }
    
    // 如果没有转发头, fallback到RemoteIpAddress,同时处理IPv4映射的IPv6地址
    var remoteIp = context.Connection.RemoteIpAddress;
    if (remoteIp == null)
        return "Unknown";
    
    // 把IPv4映射的IPv6地址转换为标准IPv4格式(比如把::ffff:127.0.0.1转成127.0.0.1)
    if (remoteIp.IsIPv4MappedToIPv6)
        remoteIp = remoteIp.MapToIPv4();
    
    return remoteIp.ToString();
}

然后在你的Action中调用这个方法:

[HttpGet]
public IActionResult GetClientIp()
{
    var clientIp = GetRealClientIp(HttpContext);
    return Ok(new { ClientIp = clientIp });
}

3. 本地测试的说明

本地测试时,因为没有反向代理,RemoteIpAddress会显示::1(IPv6回环地址)或者::ffff:127.0.0.1(IPv4回环地址的IPv6映射格式),这是正常现象。用上面方法中的MapToIPv4()转换后,就能显示成熟悉的127.0.0.1格式。

部署环境注意事项

  • IIS部署:确保IIS的ARR(Application Request Routing)已经配置了转发X-Forwarded-For和X-Forwarded-Proto头。
  • Nginx部署:在Nginx配置中添加proxy_set_header X-Forwarded-For $remote_addr;和proxy_set_header X-Forwarded-Proto $scheme;。
  • 云服务部署(如Azure App Service):云平台已经自动配置了转发头,只需要在ASP.NET Core中信任这些代理即可(可以通过KnownNetworks配置,或者设置options.ForwardLimit = 2;)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:48:37