.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
相关产品推荐
相关产品推荐

