如何取得wap和web用户的真实IP
来源:互联网 发布:楼天城编程能力强在哪 编辑:程序博客网 时间:2024/06/07 13:49
1 HTTP_X_FORWARDED_FOR, REMOTE_ADDR,HTTP_CLIENT_IP和HTTP_VIA的区别总结
在移动互联网中,如何才能取得用户真正的IP呢,其实我们在header中可以得到的四个参数分别为REMOTE_ADDR ,HTTP_VIA ,HTTP_X_FORWARDED_FOR ,HTTP_CLIENT_IP,这四个参数意义如下:
REMOTE_ADDR - 是你的客户端跟你的服务器“握手”时候的IP(访问客户端的 IP 地址)。如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP,REMOTE_ADDR –访问客户端的 IP 地址,有可能是用户的IP,也有可能是代理的IP。
HTTP_CLIENT_IP - 是代理服务器发送的HTTP头,代理端的IP,可能存在,可伪造。如果是“超级匿名代理”,则返回none值。同样,REMOTE_ADDR也会被替换为这个代理服务器的IP。
HTTP_X_FORWARDED_FOR -简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,只有在通过了HTTP 代理(比如APACHE代理)或者负载均衡服务器时才会添加该项。它不是RFC中定义的标准请求头信息,在squid缓存代理服务器开发文档中可以找到该项的详细介绍。如果有该条信息, 说明您使用了代理服务器,地址就是后面的数值。可以伪造。标准格式如下:X-Forwarded-For: client1, proxy1, proxy2
HTTP_VIA - 如果有该条信息, 就证明您使用了代理服务器,代理服务器的地址就是后面的数值。
1)没有使用代理服务器的情况:
REMOTE_ADDR = 您的 IP
HTTP_VIA = 没数值或不显示
HTTP_CLIENT_IP = 没数值或不显示
HTTP_X_FORWARDED_FOR = 没数值或不显示
2)使用透明代理服务器的情况:TransparentProxies
REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_VIA = 代理服务器 IP
HTTP_CLIENT_IP = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 您的真实 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
这类代理服务器还是将您的信息转发给您的访问对象,无法达到隐藏真实身份的目的。
3)使用普通匿名代理服务器的情况:AnonymousProxies
REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_VIA = 代理服务器 IP
HTTP_CLIENT_IP = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 代理服务器 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
隐藏了您的真实IP,但是向访问对象透露了您是使用代理服务器访问他们的。
4)使用欺骗性代理服务器的情况:DistortingProxies
REMOTE_ADDR = 代理服务器 IP
HTTP_VIA = 代理服务器 IP
HTTP_CLIENT_IP = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 随机的 IP ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
告诉了访问对象您使用了代理服务器,但编造了一个虚假的随机IP代替您的真实IP欺骗它。
5)使用高匿名代理服务器的情况:HighAnonymity Proxies (Elite proxies)
REMOTE_ADDR = 代理服务器 IP
HTTP_VIA = 没数值或不显示
HTTP_CLIENT_IP = 没数值或不显示
HTTP_X_FORWARDED_FOR = 没数值或不显示 ,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
完全用代理服务器的信息替代了您的所有信息,就象您就是完全使用那台代理服务器直接访问对象。
6)使用了cdn内容分发网络
由于访客不是直接访问源服务器,跟源服务打交道的都是CDN的节点机器,所以在源服务器抓取到的IP都是节点IP。这对按ip来统计的浏览量、网站统计等模块的影响会比较大。一般来说,CDN节点会以某种方式将源客户端的IP传递给源服务器,就拿我用的网宿CDN来说,它是将源IP添加到了一个叫“Cdn-Src-Ip”的Http Header里
注:Squid默认设置forwarded_for项默认是为on,如果 forwarded_for设成了 off 则:X-Forwarded-For: unknown
2 wap特有表头属性分析
Sky-Real-IP: Sky-Wapproxy的代理IP,是SKY WAP代理的请求
X-real-ip: 跟remote_addr一样,对nginx而言设置了则有不设置则无,一般nginx设置为 proxy_set_header X-real-ip $remote_addr;
x-network-info GPRS,10.139.155.216,13951615696,211.139.172.70,unsecured,移动的gprs网络信息,10.139.155.216和211.139.172.70都是WAP网关的IP,这次会话使用的是非安全的通信模式,即是没有使用安全服务层(TLS或者WTLS),13951615696是你们省网关的GT码
x-forwarded-for 10.139.155.216, 10.139.155.215 同HTTP_X_FORWARDED_FOR
x-source-id 连接模式,一般是本地局域网IP
client-ip:终端的IP即终端上网时动态分配的IP(clientip)有可能是内网IP
clientip: 使用UCWEB时uc带上的客户端IP
3 关于Proxy-Client-IP和WL-Proxy-Client-IP
在apache+WebLogic整合系统中,apache会对request对象进行再包装,附加一些WLS要用的头信息,两个信息如下:
Proxy-Client-IP 代理客服端IP
WL-Proxy-Client-IP WebLogic代理客服端IP(weblogic设置了才会有这个参数)
一般情况下Proxy-Client-IP和WL-Proxy-Client-IP的IP是一样的
在Linux加Squid的组合做为代理服务器的网络环境中,若Squid的配置forwarded_for 设成了 off则:X-Forwarded-For: unknown。此时在apache+WebLogic的系统中Proxy-Client-IP和WL-Proxy-Client-IP可以反应出用户的真实IP
4 如何取得用户真实的IP
综上所述:
正确的取得wap用户IP的逻辑应该是
1. 判断clientip是否为空,若不为空则取
2. 判断x-forwarded-for是否有值
3. 若有值判断是否是“unknown”若不是则此时用户IP为x-forwarded-for中第一个不为unknown且不是当前内网的IP。
4. 若x-forwarded-for无值或为“unknown”则看Proxy-Client-IP和WL-Proxy-Client-IP中是否有值,若有取此值,若无取REMOTE_ADDR作为用户IP
流程图如下:
下面是java代码:
package com.ecom;import org.apache.commons.lang3.StringUtils;import javax.servlet.http.HttpServletRequest;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.*;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * Created with IntelliJ IDEA. * User: R * Date: 13-8-1 * Time: 上午11:34 * To change this template use File | Settings | File Templates. */public class RealIpUtils { /** * 取所有IP段的私有IP段 * A类 私有地址 10.0.0.0---10.255.255.255 保留地址 127.0.0.0---127.255.255.255 * B类 私有地址 172.16.0.0-172.31.255.255 * C类 私有地址 192.168.0.0-192.168.255.255 * D类 地址不分网络地址和主机地址 * E类 地址不分网络地址和主机地址 */ private static long aBegin = getIpNum("10.0.0.0"); private static long aEnd = getIpNum("10.255.255.255"); private static long bBegin = getIpNum("172.16.0.0"); private static long bEnd = getIpNum("172.31.255.255"); private static long cBegin = getIpNum("192.168.0.0"); private static long cEnd = getIpNum("192.168.255.255"); private static long saveBegin = getIpNum("127.0.0.0"); private static long saveEnd = getIpNum("127.255.255.255"); //跟IP有关需要做判断的header参数 private static Set<String> ipHeaderNames = new HashSet<String>(){ { add("clientip");//终端的IP即终端上网时动态分配的IP add("x-forwarded-for");//简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP add("proxy-client-ip");//代理客服端IP add("wl-proxy-client-ip");//WebLogic代理客服端IP(weblogic设置了才会有这个参数) } }; public static String getRealIpAddr(HttpServletRequest request) { System.out.println("-------------getRealIpAddr start---------------------"); //防止在header中的参数名有大小写之分,重新将需要处理的参数值和内容装填入Map中 Map<String,String> ipHeaders = new HashMap<String,String>(); Enumeration<String> headerNames = request.getHeaderNames(); StringBuilder headerNamesStr = new StringBuilder(); while (headerNames.hasMoreElements()){ String nowName = headerNames.nextElement(); headerNamesStr.append(nowName+","); if(ipHeaderNames.contains(nowName.toLowerCase())){ ipHeaders.put(nowName.toLowerCase(),request.getHeader(nowName));//装填key和value } } System.out.println("headerNamesStr : "+headerNamesStr); //取正确的IP String ipAddress = null; ipAddress = ipHeaders.get("clientip");//取clientip与client-ip有区别 System.out.println("clientip:"+ipAddress); if(ipAddress!=null&&isInnerIP(ipAddress)){//若取得的clientip是内网IP,则置为0 ipAddress = null; } //若clientip为空或者是内网IP则取x-forwarded-for if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)){ String xForwardedIpAddress = ipHeaders.get("x-forwarded-for"); System.out.println("x-forwarded-for:"+ipAddress); //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 if (StringUtils.isNotEmpty(xForwardedIpAddress)) { String[] ipList = xForwardedIpAddress.split(","); for (String nowIp : ipList) { if(isIpAddress(nowIp)&&!isInnerIP(nowIp)){//取第一个不是内网IP的IP作为真实IP ipAddress = nowIp; break; } } } } //若x-forwarded-for为空则取proxy-client-ip if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = ipHeaders.get("proxy-client-ip"); System.out.println("proxy-client-ip:"+ipAddress); } //若proxy-client-ip为空则取wl-proxy-client-ip if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = ipHeaders.get("wl-proxy-client-ip"); System.out.println("wl-proxy-client-ip:"+ipAddress); } //若wl-proxy-client-ip为空则取RemoteAddr if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); System.out.println("remote-addr:"+ipAddress); if (ipAddress.equals("127.0.0.1")) { //根据网卡取本机配置的IP InetAddress inet = null; try { inet = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } ipAddress = inet.getHostAddress(); } } System.out.println("real-ip:"+ipAddress); System.out.println("-------------getRealIpAddr end---------------------"); return ipAddress; } public static boolean isInnerIP(String ipAddress) { boolean isInnerIp = false; long ipNum = getIpNum(ipAddress); isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || isInner(ipNum, saveBegin, saveEnd); return isInnerIp; } private static long getIpNum(String ipAddress) { String[] ip = ipAddress.split("\\."); long a = Integer.parseInt(ip[0]); long b = Integer.parseInt(ip[1]); long c = Integer.parseInt(ip[2]); long d = Integer.parseInt(ip[3]); long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d; return ipNum; } private static boolean isInner(long userIp, long begin, long end) { return (userIp >= begin) && (userIp <= end); } /** * 检验是否是合法的IP地址 * @param address String IP地址 * @return boolean IP地址是否合法 */ public static boolean isIpAddress(String address) { if(StringUtils.isEmpty(address)) return false; String regex = "(((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))[.](((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))[.]" + "(((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))[.](((2[0-4]d)|(25[0-5]))|(1d{2})|([1-9]d)|(d))"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(address); return m.matches(); }}
- 如何取得wap和web用户的真实IP
- 转载:如何取得wap和web用户的真实IP
- 服务器取得用户的真实ip
- 如何获取用户的真实IP
- java如何获取用户真实的ip
- 如何取得nginx做反向代理时的真实IP?
- 一个取得真实IP地址的方法
- JavaWeb如何尽可能的获取到用户的真实IP
- jsp如何获取用户的真实IP地址...
- JSP如何获取用户的真实IP地址[转载]
- request.getRemoteAddr()如何获取用户真实的IP地址
- Discuz网站如何获取用户的真实IP?
- JSP如何获取用户的真实IP地址
- request.getRemoteAddr()如何获取用户真实的IP地址
- 取得客户端真实IP
- 取得客户端真实ip
- 获取用户的真实ip
- 如何通过Request获取用户真实IP
- CPU知识进阶篇——CPU架构及性能参数解析
- YARN 中 Container 的启动
- 线性表简介
- Web.xml中Listener的使用
- boost::condition_variable 设计c++ 生产者消费者队列
- 如何取得wap和web用户的真实IP
- 代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性
- IT人 不要一辈子靠技术生存
- HTTP协议详解-转
- Oracle的to_date函数
- 3.2.7Menu2
- 电子政务行业的数据中心测试
- Python MySQLdb库的一点说明 02
- 巅峰之作 IBM Power 7处理器架构分析