在使用負載均衡的情況下,通過 context.Connection.RemoteIpAddress 獲取到的是負載均衡的 IP 地址,需要通過 X-Forwarded-For 請求頭才能獲取到客戶端的真實 IP 。
之前采用的方式是自己直接獲取 X-Forwarded-For 請求頭,代碼如下:
public static class HttpContextExtensions { public static string GetUserIp(this HttpContext context) { var ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault(); if (string.IsNullOrEmpty(ip)) { ip = context.Connection.RemoteIpAddress?.ToString(); } return GetSingleIP(ip); } private static string GetSingleIP(string ip) { if (!string.IsNullOrEmpty(ip)) { var commaIndex = ip.LastIndexOf(","); if (commaIndex >= 0) { ip = ip.Substring(commaIndex + 1); } } return ip; } }
現在改用 asp.net core 內置的 Forwarded Headers Middleware 來實現。
先在 Startup.ConfigureServices 中配置 ForwardedHeadersOptions ,對於獲取客戶端 IP 的場景只需要指定 ForwardedHeaders.XForwardedFor 。
services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; options.KnownNetworks.Clear(); options.KnownProxies.Clear(); });
注1:如果負載均衡不是在本機通過 Loopback 地址轉發請求的,一定要加上 options.KnownNetworks.Clear 與 options.KnownProxies.Clear 。
注2:如果設置環境變量 ASPNETCORE_FORWARDEDHEADERS_ENABLED 為 true ,就不需要上面的配置代碼。
然后在 Startup.Configure 中添加 Forwarded Headers 中間件。
app.UseForwardedHeaders()
這樣就可以通過 RemoteIpAddress 獲取客戶端的真實 IP 地址了。
var ip = Request.HttpContext.Connection.RemoteIpAddress?.MapToIPv4().ToString();