如何在 ASP.NET CORE 中获取客户端 IP ?
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在 ASP.NET CORE 中获取客户端 IP ?相关的知识,希望对你有一定的参考价值。
咨询区
eadam:
在 ASP.NET 中我可以用 Request.ServerVariables["REMOTE_ADDR"]
来获取客户端IP地址,请问在 ASP.NET Core 中我该如何实现呢?
回答区
CodingYourLife
如果你用的是 .NET 5
,可以用内部提供的扩展方法来实现获取客户端IP,参考代码如下:
public static class HttpContextExtensions
{
//https://gist.github.com/jjxtra/3b240b31a1ed3ad783a7dcdb6df12c36
public static IPAddress GetRemoteIPAddress(this HttpContext context, bool allowForwarded = true)
{
if (allowForwarded)
{
string header = (context.Request.Headers["CF-Connecting-IP"].FirstOrDefault() ?? context.Request.Headers["X-Forwarded-For"].FirstOrDefault());
if (IPAddress.TryParse(header, out IPAddress ip))
{
return ip;
}
}
return context.Connection.RemoteIpAddress;
}
}
然后像下面这样调用。
var ipFromExtensionMethod = HttpContext.GetRemoteIPAddress().ToString();
crokusek:
在 ASP.NET Core 的世界里,一般都会在 Kestrel 前加上 IIS 或 nginx 做负载均衡,在这种场景下获取客户端IP需要做一些额外处理,那就是在 Http Header 头上增加 X-Forwarded-For
标记,其实不管有没有负载均衡,建议都加上,参考代码如下:
public string GetRequestIP(bool tryUseXForwardHeader = true)
{
string ip = null;
// todo support new "Forwarded" header (2014) https://en.wikipedia.org/wiki/X-Forwarded-For
// X-Forwarded-For (csv list): Using the First entry in the list seems to work
// for 99% of cases however it has been suggested that a better (although tedious)
// approach might be to read each IP from right to left and use the first public IP.
// http://stackoverflow.com/a/43554000/538763
//
if (tryUseXForwardHeader)
ip = GetHeaderValueAs<string>("X-Forwarded-For").SplitCsv().FirstOrDefault();
// RemoteIpAddress is always null in DNX RC1 Update1 (bug).
if (ip.IsNullOrWhitespace() && _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress != null)
ip = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
if (ip.IsNullOrWhitespace())
ip = GetHeaderValueAs<string>("REMOTE_ADDR");
// _httpContextAccessor.HttpContext?.Request?.Host this is the local host.
if (ip.IsNullOrWhitespace())
throw new Exception("Unable to determine caller's IP.");
return ip;
}
public T GetHeaderValueAs<T>(string headerName)
{
StringValues values;
if (_httpContextAccessor.HttpContext?.Request?.Headers?.TryGetValue(headerName, out values) ?? false)
{
string rawValues = values.ToString(); // writes out as Csv when there are multiple.
if (!rawValues.IsNullOrWhitespace())
return (T)Convert.ChangeType(values.ToString(), typeof(T));
}
return default(T);
}
public static List<string> SplitCsv(this string csvList, bool nullOrWhitespaceInputReturnsNull = false)
{
if (string.IsNullOrWhiteSpace(csvList))
return nullOrWhitespaceInputReturnsNull ? null : new List<string>();
return csvList
.TrimEnd(',')
.Split(',')
.AsEnumerable<string>()
.Select(s => s.Trim())
.ToList();
}
public static bool IsNullOrWhitespace(this string s)
{
return String.IsNullOrWhiteSpace(s);
}
点评区
确实在获取客户端IP的时候要考虑到 X-Forwarded-For
,毕竟对外的业务系统都是按集群为单位对外提供服务的,学习了。
以上是关于如何在 ASP.NET CORE 中获取客户端 IP ?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ASP.NET Core 2.1 中获取客户端 IP 地址
ASP.NET Core 3.1 - 如何获取客户端的 IP 地址?
当服务器位于 AWS ELB 之后时,ASP.NET Core MVC 应用程序如何获取客户端 IP 地址?