在 .NET Core 中获取客户端 IP 地址和位置信息

概述:本文将教我们如何在 ASP .NET Core Web 开发中检索客户端的 IP 地址和位置信息。从 HttpContext 检索客户端 IP在 ASP.NET Core 中,您可以轻松地从 Controller 中的 HttpContext 对象获取客户端 IP 地址,从而在 Web 请求期间轻松访问以下重要信息:public class MyIpController : ControllerBase {     [HttpGet]     public ActionResult Get()     {         var ipAddress = HttpContext.Con

本文将教我们如何在 ASP .NET Core Web 开发中检索客户端的 IP 地址和位置信息。

从 HttpContext 检索客户端 IP

在 ASP.NET Core 中,您可以轻松地从 Controller 中的 HttpContext 对象获取客户端 IP 地址,从而在 Web 请求期间轻松访问以下重要信息:

public class MyIpController : ControllerBase  
{  
    [HttpGet]  
    public ActionResult Get()  
    {  
        var ipAddress = HttpContext.Connection.RemoteIpAddress?.ToString();  
        // ...  
    }  
}

当我们的应用程序直接暴露在互联网上时,这种方法非常有效,无需反向代理的中间层即可运行。

检索反向代理背后的真实客户端 IP

但是,大多数 Web 应用程序在其体系结构中使用中间层(如反向代理或负载均衡器)是很常见的。

直接检索方法可能会生成代理 IP,而不是客户端的 IP。

要获取实际客户端的 IP 地址,我们可以从_“X-Forwarded-For”_标头值中提取它。

为此,我们必须首先在_Program.cs_中配置 ForwardHeaderOptions

// forward headers configuration for reverse proxy  
builder.Services.Configure\<ForwardedHeadersOptions>(options => {  
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;  
    options.KnownNetworks.Clear();  
    options.KnownProxies.Clear();  
});

然后,在控制器中,我们可以检索实际的客户端 IP 地址:

public class MyIpController : ControllerBase  
{  
    [HttpGet]  
    public ActionResult Get()  
    {  
        var ipAddress = HttpContext.GetServerVariable("HTTP_X_FORWARDED_FOR");  
        // ...  
    }  
}

检索 Cloudflare 背后的真实客户端 IP

如果我们使用 Cloudflare,我们可以从_“CF-CONNECTING-IP”_标头访问真正的客户端 IP:

public class MyIpController : ControllerBase  
{  
    [HttpGet]  
    public ActionResult Get()  
    {  
        var ipAddress = Request.Headers["CF-CONNECTING-IP"];  
        // ...  
    }  
}

获取客户端的 IP 位置信息

为了根据客户的IP地址获取位置信息,我们将利用 ip-api.com 提供的服务。

首先,我们创建 IpApiClient 类:

public class IpApiClient(HttpClient httpClient)  
{  
    private const string BASE_URL = "http://ip-api.com";  
    private readonly HttpClient _httpClient = httpClient;  
  
    public async Task<IpApiResponse?> Get(string? ipAddress, CancellationToken ct)  
    {  
        var route = $"{BASE_URL}/json/{ipAddress}";  
        var response = await _httpClient.GetFromJsonAsync<IpApiResponse>(route, ct);  
        return response;  
    }  
}

IpApiResponse 类:

public sealed class IpApiResponse  
{  
    public string? status { get; set; }  
    public string? continent { get; set; }  
    public string? country { get; set; }  
    public string? regionName { get; set; }  
    public string? city { get; set; }  
    public string? district { get; set; }  
    public string? zip { get; set; }  
    public double? lat { get; set; }  
    public double? lon { get; set; }  
    public string? isp { get; set; }  
    public string? query { get; set; }  
}

我们需要在服务容器中添加并注册 IpApiClient 的 HttpClient,这可以在 Program.cs 文件中完成:

builder.Services.AddHttpClient<IpApiClient>();

现在我们可以检索客户端的 IP 位置信息:

[HttpGet]  
public async Task<ActionResult> Get(CancellationToken ct)  
{  
    try  
    {  
        var ipAddress = HttpContext.GetServerVariable("HTTP_X_FORWARDED_FOR") ?? HttpContext.Connection.RemoteIpAddress?.ToString();  
        var ipAddressWithoutPort = ipAddress?.Split(':')[0];  
  
        var ipApiResponse = await _ipApiClient.Get(ipAddressWithoutPort, ct);  
  
        var response = new  
        {  
            IpAddress = ipAddressWithoutPort,  
            Country = ipApiResponse?.country,  
            Region = ipApiResponse?.regionName,  
            City = ipApiResponse?.city,  
            District = ipApiResponse?.district,  
            PostCode = ipApiResponse?.zip,  
            Longitude = ipApiResponse?.lon.GetValueOrDefault(),  
            Latitude = ipApiResponse?.lat.GetValueOrDefault(),  
        };  
  
        return Ok(response);  
    }  
    catch (Exception ex)  
    {  
        return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);  
    }  
}  

有时,客户端 IP 包含端口号。
我们可以使用以下代码删除端口号:
var ipAddressWithoutPort = ipAddress?.Split(':')[0];

我创建了一个简单的应用程序来展示本文中讨论的概念:

图片

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值