📌  相关文章
📜  Request.ServerVariables["HTTP_X_FORWARDED_FOR"] 只获取一个 ipaddress - C# (1)

📅  最后修改于: 2023-12-03 15:34:42.701000             🧑  作者: Mango

以 'Request.ServerVariables["HTTP_X_FORWARDED_FOR"]' 只获取一个 ipaddress - C#

在 ASP.NET 中,可以使用 Request.ServerVariables["HTTP_X_FORWARDED_FOR"] 获取请求中的客户端 IP 地址。然而,这个方法只能获取一个 IP 地址,不适用于一些特定的场景。

问题描述

假设我们有一个 Web 应用程序 A,它有一个页面 P,然后在另一个 Web 应用程序 B 中嵌入了这个页面 P。在这种情况下,如果我们使用 Request.ServerVariables["HTTP_X_FORWARDED_FOR"] 获取客户端 IP 地址,它只会返回 B 服务器的 IP 地址,而无法获取真实用户的 IP 地址。

因为在这种嵌套网页的情况下,HTTP_X_FORWARDED_FOR 变量所代表的 IP 地址是中间服务器(即应用程序 B 服务器)传送到应用程序 A 服务器上的,而不是客户端的真实 IP 地址。

所以,这个方法不适用于所有特殊场景下的 IP 获取需求。

解决方案

为了解决这个问题,我们需要使用更准确的方式来获取客户端的真实 IP 地址。正确的方式是获取 HTTP 请求报文头中的 X-Real-IP 或者 X-Forwarded-For 字段。

例如,使用下面的方法来获取请求中的真实 IP 地址:

public string GetClientIpAddress(HttpContext context)
{
    // 先获取 X-Real-IP 字段
    var ip = context.Request.Headers["X-Real-IP"];

    // 如果没有就获取 X-Forwarded-For 字段
    if (string.IsNullOrWhiteSpace(ip))
    {
        ip = context.Request.Headers["X-Forwarded-For"].ToString().Split(new char[] { ',' }).FirstOrDefault();
    }

    // 如果仍然没有,就获取 RemoteIpAddress 属性提供的 IP 地址
    if (string.IsNullOrWhiteSpace(ip))
    {
        ip = context.Connection.RemoteIpAddress.ToString();
    }

    return ip;
}

这个方法考虑了前述场景,首先检查 X-Real-IP 字段是否存在,如果不存在就获取 X-Forwarded-For 字段的第一个 IP 地址,如果还是没有,就获取 RemoteIpAddress 属性提供的地址。

总结

通过正确的获取方式,我们可以获取到客户端的真实 IP 地址,无论请求是从哪里发出的。Request.ServerVariables["HTTP_X_FORWARDED_FOR"] 可以作为一种获取客户端 IP 地址的手段之一,但是在需要真实 IP 地址的场景下,建议使用更为准确的方式。