ASP.NET Core 获取客户端 IP 地址的处理方法
在基于 ASP.NET Core 的应用中,准确获取客户端的 IP 地址是常见需求,尤其是在有反向代理服务器(如 Nginx、Apache 或 Azure Application Gateway)的情况下,需要正确配置才能获取到实际的客户端 IP。
一、标准获取客户端 IP 的方法
在 ASP.NET Core 中,可以通过 HttpContext.Connection.RemoteIpAddress
获取客户端 IP 地址:
public IActionResult GetClientIp()
{
var clientIp = HttpContext.Connection.RemoteIpAddress?.ToString();
return Ok(clientIp);
}
但是在有反向代理的情况下,这个方法通常会返回代理服务器的 IP,而非真实客户端的 IP。
二、使用 X-Forwarded-For
头获取真实客户端 IP
当应用部署在反向代理服务器后,代理通常会将真实客户端 IP 写入 X-Forwarded-For
请求头中。
1. 启用 ForwardedHeaders
中间件
ASP.NET Core 提供了 ForwardedHeadersMiddleware
来解析 X-Forwarded-For
和 X-Forwarded-Proto
头。需要在 Startup
或 Program
文件中启用。
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 配置中间件以处理转发的头部
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
// 信任所有代理服务器
ForwardLimit = null, // 不限制转发层数
KnownNetworks = { }, // 清空默认信任的网络范围
KnownProxies = { } // 清空默认信任的代理 IP
});
app.MapGet("/client-ip", (HttpContext context) =>
{
var clientIp = context.Connection.RemoteIpAddress?.ToString();
var forwardedIp = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
return$"Client IP: {clientIp}, Forwarded IP: {forwardedIp}";
});
app.Run();
2. 配置反向代理
确保反向代理正确地设置了 X-Forwarded-For
头。
- Nginx 配置示例:
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:5000;
}
- Apache 配置示例:
ProxyPass / http://localhost:5000/
ProxyPassReverse / http://localhost:5000/
RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
RequestHeader add X-Forwarded-For %{REMOTE_ADDR}e
三、常见问题及解决方案
1. 未启用 ForwardedHeaders
中间件
如果未启用 UseForwardedHeaders
,即使反向代理正确配置了 X-Forwarded-For
,应用仍然无法读取真实 IP。
2. 信任的代理服务器配置不当
默认情况下,ASP.NET Core 仅信任本地主机。如果需要信任所有代理服务器,可以清空 KnownNetworks
和 KnownProxies
,并设置 ForwardLimit
为 null
。
3. 多级代理的处理
如果请求经过多个代理服务器,X-Forwarded-For
中会包含以逗号分隔的多个 IP 地址,最左侧的 IP 通常是客户端的真实 IP。
var forwardedHeader = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
var clientIp = forwardedHeader?.Split(',')[0].Trim();
四、使用中间件封装获取 IP 的逻辑
为了便于复用,可以创建一个中间件封装获取客户端真实 IP 的逻辑:
public classClientIpMiddleware
{
privatereadonly RequestDelegate _next;
public ClientIpMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var forwardedIp = context.Request.Headers["X-Forwarded-For"].FirstOrDefault()?.Split(',')[0].Trim();
var clientIp = forwardedIp ?? context.Connection.RemoteIpAddress?.ToString();
context.Items["ClientIp"] = clientIp;
await _next(context);
}
}
// 注册中间件
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseMiddleware<ClientIpMiddleware>();
app.MapGet("/client-ip", (HttpContext context) =>
{
return context.Items["ClientIp"]?.ToString() ?? "Unknown";
});
app.Run();
五、总结
- 获取客户端 IP:
HttpContext.Connection.RemoteIpAddress
是基础,但需要处理代理情况。 - 使用中间件:
UseForwardedHeaders
解析X-Forwarded-For
。 - 反向代理配置:确保代理服务器正确设置了转发头。
- 多级代理支持:解析
X-Forwarded-For
中的多个 IP 地址。 - 信任所有代理:通过配置
ForwardLimit
和清空默认信任的范围实现。
通过以上方法,可以在任何部署环境中正确获取客户端的真实 IP 地址。
作者:阿笨
【官方QQ一群:跟着阿笨一起玩NET(已满)】:422315558
【官方QQ二群:跟着阿笨一起玩C#(已满)】:574187616
【官方QQ三群:跟着阿笨一起玩ASP.NET(已满)】:967920586
【官方QQ四群:Asp.Net Core跨平台技术开发(可加入)】:829227829
【官方QQ五群:.NET Core跨平台开发技术(可加入)】:647639415
【网易云课堂】:https://study.163.com/provider/2544628/index.htm?share=2&shareId=2544628
【51CTO学院】:https://edu.51cto.com/sd/66c64
【微信公众号】:微信搜索:跟着阿笨一起玩NET
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2021-02-04 SQL Server数据库高级进阶之事务实战演练
2021-02-04 C#如何正确运用异步编程技术
2021-02-04 SQL Server数据库高级进阶之锁实战演练
2020-02-04 .NET Core基于SQL Server数据库主从同步实现读写分离实战演练
2013-02-04 将要被社会淘汰的8种人