客戶端直接訪問服務器
直接通過HttpContext.Connection.RemoteIpAddress獲取客戶端Ip
[HttpGet]
[Route("GetClientIP")]
public async Task<IActionResult> GetClientIP()
{
var ip4 = HttpContext.Connection.RemoteIpAddress.MapToIPv4();
return Ok(ip4.ToString());
}
客戶端通過nginx訪問服務器
直接通過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 請求。以下是一些使用場景:
-
反向代理服務器:當你的應用程序位於反向代理服務器(如 Nginx、Apache 或 IIS)之後時,反向代理服務器會接收客戶端請求,並將請求轉發給應用程序。在這種情況下,反向代理服務器可能會修改請求頭部,包括客戶端 IP 地址和協議信息。通過啓用 HttpOverrides 中間件並配置適當的選項,你可以獲得客戶端的真實 IP 地址和協議信息。
-
負載均衡器:如果你的應用程序在負載均衡器的後面運行,負載均衡器可能會傳遞客戶端請求給多個實例。爲了獲取準確的客戶端 IP 地址,你可以使用 HttpOverrides 中間件來識別 X-Forwarded-For 頭部字段,並更新 HttpContext.Connection.RemoteIpAddress 屬性。
-
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
- 安裝 Nuget 包 IP2Region.Net。
Install-Package IP2Region.Net
- 使用demo
查詢IP返回的數據格式
每個 ip 數據段的 region 信息都固定了格式:國家|區域|省份|城市|ISP,只有中國的數據絕大部分精確到了城市,其他國家部分數據只能定位到國家,後前的選項全部是0。