代码示例:
using Microsoft.AspNetCore.Mvc; using System.Net; [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { [HttpGet] public IActionResult GetClientIP() { // 从 HttpContext 中获取连接对象,并通过 RemoteIpAddress 属性获取客户端 IP 地址 var clientIpAddress = HttpContext.Connection.RemoteIpAddress?.MapToIPv4()?.ToString(); return Ok(new { clientIpAddress }); } }
原理:HttpContext.Connection.RemoteIpAddress 直接提供了与客户端建立连接的远程 IP 地址,如果使用了反向代理服务器,可能需要额外处理以获取真实的客户端 IP 地址,例如通过请求头中的X-Forwarded-For 字段。
2、使用依赖注入和中间件获取真实 IP 地址
代码示例:
中间件实现:
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using System.Threading.Tasks; using System.Net; public class RealIpMiddleware { private readonly RequestDelegate _next; public RealIpMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { if (context.Request.Headers.ContainsKey("X-Forwarded-For")) { // 从请求头中获取 X-Forwarded-For 字段的第一个非空 IP 地址作为客户端 IP 地址 context.Connection.RemoteIpAddress = IPAddress.Parse(context.Request.Headers["X-Forwarded-For"].ToString().Split(',', StringSplitOptions.RemoveEmptyEntries)[0].Trim()); } await _next(context); } }
注册中间件:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseMiddleware(); // 其他中间件配置... }
原理:当使用反向代理服务器时,客户端的真实 IP 地址通常会被存储在请求头的X-Forwarded-For 字段中,通过自定义中间件,可以在请求处理管道中提前解析并设置正确的客户端 IP 地址。
3、在控制器构造函数中注入IHttpContextAccessor 并使用
代码示例:
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System.Net; [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private readonly ILogger_logger; private readonly IHttpContextAccessor _httpContextAccessor; public WeatherForecastController(ILogger logger, IHttpContextAccessor httpContextAccessor) { _logger = logger; _httpContextAccessor = httpContextAccessor; } [HttpGet] public IActionResult GetClientIP() { // 通过注入的 IHttpContextAccessor 获取 HttpContext,再从中获取客户端 IP 地址 var clientIpAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress?.MapToIPv4()?.ToString(); return Ok(new { clientIpAddress }); } }
原理:IHttpContextAccessor 提供了一个访问当前 HTTP 上下文的方法,可以在控制器或其他需要的地方通过它来获取HttpContext 对象,进而获取客户端 IP 地址等信息,这种方式适用于需要在多个地方访问 HTTP 上下文信息的场景。
表格对比不同方法的特点
方法
优点
缺点
适用场景
HttpContext.Connection.RemoteIpAddress
简单直接,无需额外配置和依赖注入,适用于未使用反向代理服务器或对性能要求较高的简单应用。
无法直接获取通过反向代理服务器的真实客户端 IP 地址,需要结合其他方式处理。
本地开发测试、小型项目或未使用反向代理的简单网络应用。
依赖注入和中间件获取真实 IP 地址
能够准确获取通过反向代理服务器的真实客户端 IP 地址,可扩展性强,适用于各种复杂的网络环境和应用架构。
实现相对复杂,需要额外的中间件编写和配置。
使用反向代理服务器的项目,如部署在云服务器上的应用、企业内部网络应用等。
在控制器构造函数中注入IHttpContextAccessor 并使用
方便在控制器的各个方法中统一获取 HTTP 上下文相关信息,代码结构清晰,易于维护和扩展。