如何在 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 地址?

ASP.NET Core:如何获取远程 IP 地址?

如何在 asp.net core 中使用 websockets

如何在 ASP.NET Core 3.1 中启用多重身份验证?