赞
踩
概述:本文将教我们如何在 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 地址和位置信息。
在 ASP.NET Core 中,您可以轻松地从 Controller 中的 HttpContext 对象获取客户端 IP 地址,从而在 Web 请求期间轻松访问以下重要信息:
- public class MyIpController : ControllerBase
- {
- [HttpGet]
- public ActionResult Get()
- {
- var ipAddress = HttpContext.Connection.RemoteIpAddress?.ToString();
- // ...
- }
- }
当我们的应用程序直接暴露在互联网上时,这种方法非常有效,无需反向代理的中间层即可运行。
但是,大多数 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,我们可以从_“CF-CONNECTING-IP”_标头访问真正的客户端 IP:
- public class MyIpController : ControllerBase
- {
- [HttpGet]
- public ActionResult Get()
- {
- var ipAddress = Request.Headers["CF-CONNECTING-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];
我创建了一个简单的应用程序来展示本文中讨论的概念:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。