JavaWeb应用如何判断用户真实IP?
首先最自然的想到是通过HttpServletRequest.getRemoteAddr();但是这里存在一个代理问题,即用户通过代理访问,那么这种方法就是获得代理的IP。因此如果某些场景如果对频率有限制,这样可能会造成误伤(使用同一个代理的人因为一个人超过频次限制而全部人被限制访问)。
再次通过查找资料方法有类似这样的方法
public String getIpAddr(HttpServletRequest request) {
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}
但此时,又存在问题,即HTTP头饰由客户端自行填写的,也就是说,如果存在恶意用户,那么这种判断逻辑还不如HttpServletRequest.getRemoteAddr();,至少没有办法伪造ip,采用这种方法,其实对于判断就是形同虚设。
我暂时的办法只能是第一种,尽管有误伤的可能性,但至少保证了系统的可靠性。对于第二种方法,我个人认为通过Http Header来判断显然是略显草率。那么请教各位有相关经验的朋友,如何才能兼顾获取IP地址的可靠性(在客户端使用代理的情况下)并尽可能的降低误伤几率呢?
1楼(未知网友)
talk is cheap ,show me the code (屁话少说,放码过来)。。
直接上代码吧
if (request == null)
return "";
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
2楼(未知网友)
不能,要综合判断:
如果使用常规代理的话,HTTP流可能有x-forwarded-for头,正如你所说讲,不是强制而且可以伪造。
一般逻辑可以这样考虑:将访问来的IP用whois检查一下。如果来自如一些VPS供应商的,再检查这些IP来的连接的UA。如果非浏览器UA,可能是寄存在VPS的机器人;如果是不同的浏览器UA,可能是一个代理,就要检查下HTTP的x-forwarded-for头,或者只用一些控件(例如flash)来让其汇报本地的IP。