本文将教我们如何在 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 = "https://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];
我创建了一个简单的应用程序来展示本文中讨论的概念:
源代码获取:公众号回复消息【code:51510
】