基于Nginx反向代理获取真实IP的问题详解

  

  

前文Nginx解决WebApi跨域二次请求以及Vue单页面问题当中虽然解决了跨域问题带来的二次请求,但也产生了一个新的问题,就是如果需要获取用户IP的时候,获取的IP地址总是本机地址。

  

  

由于Nginx反向代理后,在应用中取得的IP都是反向代理服务器的IP,取得的域名也是反向代理配置的Url的域名。

  

  

解决该问题,需要在Nginx反向代理配置中添加一些配置信息,目的将客户端的真实IP和域名传递到应用程序中,同时,也要修改获取IP地址的方法。

  

但是需要注意的是,通过Nginx反向代理后,如果访问IP通过了几层代理,可能取得的IP地址是这种格式:clientIP, proxy1 proxy2。

  

如果需要将IP地址插入到数据库的话,需要做防止注入。因此要对上述的IP地址的格式进行截取。

  

<强> 3.1 Nginx配置如下

        服务器{   听9461;#监听端口号   server_name localhost 192.168.88.22;#访问地址   位置/{   根项目路径;#例如:E:/发布/xxx/;   指数index . html;      #此处用于处理Vue,棱角分明,使反应用H5的历史时重写的问题   如果(!- e request_filename美元){   重写^(. *)/索引。html去年;   打破;   }   }      #代理服务端接口   位置/api {   proxy_pass http://localhost: 9460/api; #代理接口地址   #主机配置以及域名传递   proxy_set_header主机主机美元;   proxy_set_header X-Real-IP remote_addr美元;   proxy_set_header远程主机remote_addr美元;   proxy_set_header X-Forwarded-For proxy_add_x_forwarded_for美元;   }   }      

<强> c# 3.2代码获取真实IP方法

        #地区Ip(客户端Ip地址)///& lt; summary>///客户端IP地址///& lt;/summary>   公共静态字符串Ip   {   得到   {   结果var=string.Empty;   如果(HttpContext。当前!=null)   {   结果=GetWebClientIp ();   }   如果(string.IsNullOrWhiteSpace(结果))   {   结果=GetLanIp ();   }   返回结果;   }   }///& lt; summary>///获取网络客户端的IP///& lt;/summary>///& lt; returns> & lt;/returns>   私有静态字符串GetWebClientIp ()   {   var ip=GetWebProxyRealIp () & # 63; & # 63;GetWebRemoteIp ();   foreach (var hostAddress Dns.GetHostAddresses (ip))   {   如果(hostAddress。AddressFamily==AddressFamily.InterNetwork)   {   返回hostAddress.ToString ();   }   }   返回string.Empty;   }///& lt; summary>///获取网络远程IP///& lt;/summary>///& lt; returns> & lt;/returns>   私有静态字符串GetWebRemoteIp ()   {   试一试   {   HttpContext.Current.Request返回。ServerVariables (“HTTP_X_FORWARDED_FOR”) & # 63; & # 63;   HttpContext.Current.Request。ServerVariables (“REMOTE_ADDR”) & # 63; & # 63;“”;   }   捕获(异常e)   {   返回string.Empty;   }   }///& lt; summary>///获取网络代理真实IP///& lt;/summary>///& lt; returns> & lt;/returns>   私有静态字符串GetWebProxyRealIp ()   {   var请求=HttpContext.Current.Request;   字符串ip=request.Headers.Get (“x-forwarded-for”);   如果(string.IsNullOrEmpty (ip) | |字符串。=(“未知”、ip、StringComparison.OrdinalIgnoreCase))   {   ip=request.Headers.Get (“Proxy-Client-IP”);   }   如果(string.IsNullOrEmpty (ip) | |字符串。=(“未知”、ip、StringComparison.OrdinalIgnoreCase))   {   ip=request.Headers.Get (“WL-Proxy-Client-IP”);   }   如果(string.IsNullOrEmpty (ip) | |字符串。=(“未知”、ip、StringComparison.OrdinalIgnoreCase))   {   ip=request.UserHostAddress;   }   如果(string.IsNullOrEmpty (ip))   {   返回string.Empty;   }//可能存在如下格式:X-Forwarded-For:客户端,proxy1 proxy2   如果(ip)。包含(","))   {//如果存在多个反向代理,获得的IP是一个用逗号分隔的IP集合,取第一个//X-Forwarded-For:客户端第一个   string [] ips=ip。Split(新的字符串[1]{”、“},StringSplitOptions.RemoveEmptyEntries);   var=0;   (我=0;我& lt;ips.Length;我+ +)   {   如果(ips[我]!=" ")   {//判断是否为内网IP   如果(假==IsInnerIp (ips(我)))   {   IPAddress realIp;   如果(IPAddress。TryParse (ips[我],realIp),,ips[我].Split (' . ')。长度==4)   {//合法IP   返回ips(我);   }   返回";   }   }   }   ip=ips[0];//默认获取第一个ip地址   }   返回的ip;   }///& lt; summary>///判断IP地址是否为内网IP地址///& lt;/summary>///& lt;参数name="知识产权"祝辞ip地址& lt;/param>///& lt; returns> & lt;/returns>   私有静态bool IsInnerIp (string ip)   {   bool isInnerIp=false;   ulong ipNum=Ip2Ulong (ip);/* *   *私有知识产权   *类:10.0.0.0-10.255.255.255   * B类:172.16.0.0-172.31.255.255   * C类:192.168.0.0-192.168.255.255   *当然,还这有127个网段是环回地址   */ulong aBegin=Ip2Ulong (“10.0.0.0”);   ulong aEnd=Ip2Ulong (“10.255.255.255”);   ulong bBegin=Ip2Ulong (“172.16.0.0”);   ulong弯曲=Ip2Ulong (“10.31.255.255”);   ulong cBegin=Ip2Ulong(“192.168.0.0到”);   ulong cEnd=Ip2Ulong (“192.168.255.255”);   isInnerIp=isin (ipNum aBegin aEnd) | | isin (ipNum bBegin,弯曲)| | isin (ipNum、cBegin cEnd) | |   ip.Equals (127.0.0.1);   返回isInnerIp;   }///& lt; summary>///将IP地址转换为长期型数字///& lt;/summary>///& lt;参数name="知识产权"祝辞ip地址& lt;/param>///& lt; returns> & lt;/returns>   私有静态ulong Ip2Ulong (string ip)   {   byte[]字节=IPAddress.Parse (ip) .GetAddressBytes ();   ulong ret=0;   foreach (var b以字节为单位)   {   ret & lt; & lt;=8;   ret |=b;   }   返回受潮湿腐烂;   }///& lt; summary>///判断用户IP地址转换为长期型后是否在内网IP地址所在范围///& lt;/summary>///& lt;参数name=" userIp祝辞用户IP

基于Nginx反向代理获取真实IP的问题详解