コード例 #1
0
        /// <summary>
        /// 获取IP(想获取到真实是IP,前提条件是不存在伪造,如果第一台客户机伪造了【HTTP_X_FORWARDED_FOR】,那么服务器也拿不到真实的IP)
        /// </summary>
        /// <returns></returns>
        public static string GetRealIP(this HttpRequestBase request)
        {
            //TODO: 检测【HTTP_X_FORWARDED_FOR】信息是否会引发【SQL注入】或【XSS】安全漏洞

            /*获取IP的步骤(不管是否有【nginx】反向代理服务器)
             *  1.获取【HTTP_X_REAL_IP】地址。如果有,说明是访问【nginx】的真实IP;如果没有,说明没有使用【nginx】,继续下一步
             *  2.获取【HTTP_X_FORWARDED_FOR】地址,如果有,说明使用了代理,则拿到第一个IP;如果没有,说明没有使用代理,继续下一步
             *  3.获取【UserHostAddress】地址,该地址与【REMOTE_ADDR】一致,是真实IP
             */

            try
            {
                //1.获取【HTTP_X_REAL_IP】地址
                //如果部署了【nginx】服务器,那么就获取直接访问【nginx】服务器的客户机(有可能是代理)
                string resultIp = request.GetIPOfCallNginx();

                if (!string.IsNullOrWhiteSpace(resultIp))
                {
                    return(resultIp);
                }

                //2.获取【HTTP_X_FORWARDED_FOR】地址
                resultIp = request.ServerVariables["HTTP_X_FORWARDED_FOR"];

                //可能有代理
                if (!string.IsNullOrWhiteSpace(resultIp))
                {
                    //没有"." 肯定是非IP格式
                    if (!resultIp.Contains("."))
                    {
                        resultIp = string.Empty;
                    }
                    else
                    {
                        //有","表示经过了多个代理。取第一个不是内网的IP。
                        if (resultIp.Contains(","))
                        {
                            resultIp = resultIp.Replace(" ", string.Empty)
                                       .Replace(";", string.Empty)
                                       .Replace("\"", string.Empty);

                            string[] proxyIps = resultIp.Split(",".ToCharArray()) ?? new string[] { };

                            foreach (var ip in proxyIps)
                            {
                                //是IP格式,并且不是内网地址
                                if (IsIPAddress(ip) &&
                                    ip.Substring(0, 3) != "10." &&
                                    ip.Substring(0, 7) != "192.168" &&
                                    ip.Substring(0, 7) != "172.16." &&
                                    ip.Substring(0, 7) != "172.31.")
                                {
                                    return(ip);
                                }
                            }
                        }
                        //是IP格式
                        else if (IsIPAddress(resultIp))
                        {
                            return(resultIp);
                        }
                        //内容非IP
                        else
                        {
                            resultIp = string.Empty;
                        }
                    }
                }

                //没有代理,则直接拿REMOTE_ADDR,这是真实IP
                if (string.IsNullOrWhiteSpace(resultIp))
                {
                    //【UserHostAddress】属性和http-head【REMOTE_ADDR】是一致的
                    //【REMOTE_ADDR】 是客户机TCP与我们应用服务器建立时对方的真实IP,不存在伪造
                    // 如果部署了【nginx】作为反向代理服务器,那么【REMOTE_ADDR】和【UserHostAddress】都是nginx服务器的真实IP

                    resultIp = request.UserHostAddress;
                }

                return(resultIp);
            }
            catch (Exception ex)
            {
                logger.Error(ex, "获取客户IP出现异常");

                return(string.Empty);
            }
        }