asp.net core如何获取客户端IP地址

客户端直接访问服务器

直接通过HttpContext.Connection.RemoteIpAddress获取客户端Ip

[HttpGet]
[Route("GetClientIP")]
public async Task<IActionResult> GetClientIP()
{
	var ip4 = HttpContext.Connection.RemoteIpAddress.MapToIPv4();
	return Ok(ip4.ToString());
}

客户端通过nginx访问服务器

image

直接通过HttpContext.Connection.RemoteIpAddress获取客户端Ip,就会是nginx的ip,需要通过Headers["X-Forwarded-For"]判断

[HttpGet]
[Route("GetClientIP")]
public async Task<IActionResult> GetClientIP()
{
    var ip4 = this.Request.Headers["X-Forwarded-For"].FirstOrDefault();
	if(string.IsNullOrEmpty(ip4))
	{
		this.Request.Headers["X-Forwarded-Proto"].FirstOrDefault();
	}
	if(string.IsNullOrEmpty(ip4))
	{
		ip4 = HttpContext.Connection.RemoteIpAddress.MapToIPv4();
	}
	return Ok(ip4.ToString());
}

nginx的配置
/etc/nginx/conf.d/xx.conf

server {
    listen        80;
    server_name   example.com *.example.com;
    location / {
        proxy_pass         http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $http_host; #此处官方文档使用的$host缺少端口号
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

Microsoft.AspNetCore.HttpOverrides 中间件

Microsoft.AspNetCore.HttpOverrides 中间件主要用于处理反向代理服务器和负载均衡器等情况下的 HTTP 请求。以下是一些使用场景:

  1. 反向代理服务器:当你的应用程序位于反向代理服务器(如 Nginx、Apache 或 IIS)之后时,反向代理服务器会接收客户端请求,并将请求转发给应用程序。在这种情况下,反向代理服务器可能会修改请求头部,包括客户端 IP 地址和协议信息。通过启用 HttpOverrides 中间件并配置适当的选项,你可以获得客户端的真实 IP 地址和协议信息。

  2. 负载均衡器:如果你的应用程序在负载均衡器的后面运行,负载均衡器可能会传递客户端请求给多个实例。为了获取准确的客户端 IP 地址,你可以使用 HttpOverrides 中间件来识别 X-Forwarded-For 头部字段,并更新 HttpContext.Connection.RemoteIpAddress 属性。

  3. SSL/TLS 终止器:当 SSL/TLS 终止器(如负载均衡器或反向代理服务器)接收到加密的 HTTPS 请求并解密后,它会将请求转发给应用程序时,应用程序可能无法正确获取请求的协议信息。通过配置 HttpOverrides 中间件,你可以更新 HttpContext.Request.Protocol 属性,以便应用程序知道请求是通过 HTTPS 还是 HTTP 发送的。

以下是使用 Microsoft.AspNetCore.HttpOverrides 中间件的示例代码:

首先,确保在启动类的 ConfigureServices 方法中添加以下代码以启用 HttpOverrides 服务:

using Microsoft.AspNetCore.HttpOverrides;

public void ConfigureServices(IServiceCollection services)
{
    // 其他配置项...

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        // 配置要处理的转发头部
        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
        // 配置受信任的代理服务器 IP 地址或 IP 范围
        options.KnownProxies.Add(IPAddress.Parse("127.0.0.1"));
        // 配置是否要使用逗号分隔的多个 IP 地址作为客户端 IP 地址
        options.ForwardedForHeaderName = "X-Forwarded-For";
        // 配置代理服务器发送的原始协议头部字段
        options.ForwardedProtoHeaderName = "X-Forwarded-Proto";
    });
    // 其他服务配置...
}

接下来,在 Configure 方法中将 HttpOverrides 中间件添加到请求处理管道中:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 其他中间件配置...
    app.UseForwardedHeaders();
    // 其他中间件配置...
}

配置完成后,HttpOverrides 中间件将根据设置处理传入的转发头部,并更新 HttpContext.Connection.RemoteIpAddress 和 HttpContext.Request.Protocol 属性。这样,你就可以通过 HttpContext 获取客户端的真实 IP 地址和使用的协议信息。

查询IP地址定位库(ip2region)

ip2region v2.0 - 是一个离线IP地址定位库和IP定位数据管理框架,10微秒级别的查询效率,提供了众多主流编程语言的 xdb 数据生成和查询客户端实现。

推荐使用IP2Region.Net

  1. 安装 Nuget 包 IP2Region.Net。
Install-Package IP2Region.Net
  1. 使用demo
    image

查询IP返回的数据格式

每个 ip 数据段的 region 信息都固定了格式:国家|区域|省份|城市|ISP,只有中国的数据绝大部分精确到了城市,其他国家部分数据只能定位到国家,后前的选项全部是0。

参考

https://github.com/lionsoul2014/ip2region

posted @ 2023-07-04 17:08  广州大雄  阅读(2557)  评论(7编辑  收藏  举报