前文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的问题详解