您的位置:首页 > 运维架构 > Tomcat

根据IP(有代理的情况)定位城市以及通过nginx转发的tomcat如何得到用户真实的ip

2014-11-03 15:58 781 查看

getHeader("x-forwarded-for")获取真实IP

在很多应用下都可能有需要将用户的真实IP记录下来,这时就要获得用户的真实IP地址,在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。

1.经过反向代理软件后如何得到用户真实的ip
经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的 IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。
获取用户真实的ip,可以通过以下两种方法中的一种
1)

public String getRemortIP(HttpServletRequest request) {
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}
2)

public  String getRemortIP1(HttpServletRequest request) {
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();
}
}
}else{
String[] ipArray = ip.split(",", 100);
if(ipArray != null && ipArray.length > 1){
ip = ipArray[0];
}
}
return ip;

}


如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?

答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100,那么用户真实IP为:192.168.1.110



2.通过nginx转发的tomcat如何得到用户真实的ip

经过nginx转发的tomcat,根据上面的方法得到是nginx的ip,而不是用户真实的ip.如果想得到用户真是的ip,那么必须改nginx的配置文件
server {
listen       80;
server_name  price.kuche.com;
location / {
root   html;
proxy_set_header  X-Real-IP  $remote_addr;
proxy_pass http:backServers;
}
}


JAVA根据IP地址获取详细的地域信息
在系统中,网站的头部一般都有显示是哪个城市的,用户进入到网站的首页后,默认城市应该是用户本地的城市信息,例如:北京,网站就要根据你的IP地址的信息,查询数据,获取北京部分的数据,呵呵,当然我可能描述的不是很清楚,但是可以理解成,通过IP地址定位地理信息就行。很多人现在使用以QQ数据库为基础获取地址信息,但不完整、而且不规范。互联网提供很多其他接口可以完成这项功能.
接口如下:
通过淘宝IP地址库获取IP位置
1. 请求接口(GET):http://ip.taobao.com/service/getIpInfo.php?ip=[ip地址字串]
2. 响应信息:(json格式的)国家、省(自治区或直辖市)、市(县)、运营商
3. 返回数据格式:
{"code":0,"data":{"ip":"210.75.225.254","country":"\u4e2d\u56fd","area":"\u534e\u5317",
"region":"\u5317\u4eac\u5e02","city":"\u5317\u4eac\u5e02","county":"","isp":"\u7535\u4fe1",
"country_id":"86","area_id":"100000","region_id":"110000","city_id":"110000",
"county_id":"-1","isp_id":"100017"}}
其中code的值的含义为,0:成功,1:失败。

新浪的接口 :http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=218.192.3.42
返回值
var remote_ip_info ={"ret":1,"start":"218.192.0.0","end":"218.192.7.255","country":"\u4e2d\u56fd","province":"\u5e7f\u4e1c","city":"\u5e7f\u5dde","district":"","isp":"\u6559\u80b2\u7f51","type":"\u5b66\u6821","desc":"\u5e7f\u5dde\u5927\u5b66\u7eba\u7ec7\u670d\u88c5\u5b66\u9662"};

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;

public classIptoCityUtils {

public static String Iptocity (String ip){

Stringaddress = "北京市";
try {
address= getAddresses("ip="+ip,"utf-8");
}catch(UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return address;
}

/**
*
* @param content
*           请求的参数格式为:name=xxx&pwd=xxx
* @param encoding
*           服务器端请求编码。如GBK,UTF-8等
* @return
* @throws UnsupportedEncodingException
*/
public  static String getAddresses(String content,String encodingString)
throws UnsupportedEncodingException {
// 这里调用pconline的接口
try {
String urlStr = "http://ip.taobao.com/service/getIpInfo.php";
// 从http://whois.pconline.com.cn取得IP所在的省市区信息
String returnStr = getResult(urlStr,content, encodingString);
System.out.println("returnStr="+returnStr);
if (returnStr !=null) {
// 处理返回的省市区信息
System.out.println(returnStr);
String[] temp = returnStr.split(",");
if(temp.length<3){
return"0";//无效IP,局域网测试
}

String region="北京市";

if((temp[7].split(":"))[1].replaceAll("\"","") != null &&(temp[7].split(":"))[1].replaceAll("\"","").length() != 0){
// System.out.println("hellolulu");
region =(temp[7].split(":"))[1].replaceAll("\"","");
//  System.out.println("helloluluregion="+region);
// System.out.println("region="+ ((temp[7].split(":"))[1]));
region = decodeUnicode(region);//城市
//  System.out.println("hello lulu1region="+(temp[7].split(":"))[1].replaceAll("\"","").length());
}

return region;
}

}catch(Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "北京市";
}
/**
* @param urlStr
*           请求的地址
* @param content
*           请求的参数格式为:name=xxx&pwd=xxx
* @param encoding
*           服务器端请求编码。如GBK,UTF-8等
* @return
*/
public staticString getResult(String urlStr, String content, String encoding) {
URL url = null;
HttpURLConnection connection = null;
try {
url = new URL(urlStr);
connection = (HttpURLConnection)url.openConnection();//新建连接实例
connection.setConnectTimeout(2000);//设置连接超时时间,单位毫秒
connection.setReadTimeout(2000);//设置读取数据超时时间,单位毫秒
connection.setDoOutput(true);//是否打开输出流 true|false
connection.setDoInput(true);//是否打开输入流true|false
connection.setRequestMethod("POST");//提交方法POST|GET
connection.setUseCaches(false);//是否缓存true|false
connection.connect();// 打开连接端口
DataOutputStream out = newDataOutputStream(connection
.getOutputStream());// 打开输出流往对端服务器写数据
out.writeBytes(content);// 写数据,也就是提交你的表单 name=xxx&pwd=xxx
out.flush();// 刷新
out.close();// 关闭输出流
BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream(), encoding));//往对端写完数据对端服务器返回数据
// ,以BufferedReader流来读取
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) !=null) {
buffer.append(line);
}
reader.close();
return buffer.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection !=null) {
connection.disconnect();// 关闭连接
}
}
return null;
}
/**
* unicode 转换成中文
*
* @authorfanhui 2007-3-15
* @param theString
* @return
*/
public staticString decodeUnicode(String theString) {
char aChar;
int len = theString.length();
StringBuffer outBuffer = new StringBuffer(len);
for (intx = 0; x < len;) {
aChar = theString.charAt(x++);
if (aChar =='\\'){
aChar = theString.charAt(x++);
if (aChar =='u') {
int value = 0;
for (int i = 0; i < 4; i++) {
aChar = theString.charAt(x++);
switch (aChar) {
case'0':
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
value = (value << 4) + aChar - '0';
break;
case'a':
case'b':
case'c':
case'd':
case'e':
case'f':
value = (value << 4) + 10 + aChar- 'a';
break;
case'A':
case'B':
case'C':
case'D':
case'E':
case'F':
value = (value << 4) + 10 + aChar- 'A';
break;
default:
throw new IllegalArgumentException(
"Malformed      encoding.");
}
}
outBuffer.append((char) value);
} else {
if (aChar =='t') {
aChar = '\t';
} else if (aChar == 'r'){
aChar = '\r';
} else if (aChar == 'n'){
aChar = '\n';
} else if (aChar == 'f'){
aChar = '\f';
}
outBuffer.append(aChar);
}
} else {
outBuffer.append(aChar);
}
}
return outBuffer.toString();
}

public staticvoidmain(String args[]){
Stringaddress= IptoCityUtils.Iptocity("60.209.19.27");
System.out.println("city="+address);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: