获取request请求,最重要要了解X-Forwarded-For和X-Real-IP。
X-Forwarded-For
是用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP
追加在X-Forwarded-For
中,格式如--> X-Forwarded-For:123.123.123.123,456.456.456.456,789.789.789.789,这代表请求由123.123.123.123发出然后经过多层代理。
X-Real-IP
,没有相关标准,上面的例子,如果配置了X-Read-IP
,可能会有两种情况:
// 最后一跳是正向代理,可能会保留真实客户端IP
X-Real-IP: 123.123.123.123
// 最后一跳是反向代理,比如Nginx,一般会是与之直接连接的客户端IP
X-Real-IP: 789.789.789.789
所以 ,如果只有一层代理,这两个头的值就是一样的;
下面直接上java代码:
public class IpAddressUtil {
/**
* @Author : lilong
* @Description :获取请求Ip地址
* @Date : 10:22 2018/12/27
**/
public static String getIpAdrress(HttpServletRequest request) {
//X-Real-IP,一般只记录真实发出请求的客户端IP
String XRealIp = request.getHeader("X-Real-IP");
//x_forwarded_for: 【用户经过代理时,代理会增加这个字段,nginx可用内置变量$http_x_forwarded_for取到这个字段,没有使用代理时,此字段为空】
String XForwardedFor = request.getHeader("X-Forwarded-For");
if(StringUtils.isNotEmpty(XForwardedFor) && !"unKnown".equalsIgnoreCase(XForwardedFor)){
//多次反向代理后会出现多个ip值,但只有第一个ip才是真实ip。所以只拿第一个就好
int index = XForwardedFor.indexOf(",");
if(index != -1){
return XForwardedFor.substring(0,index);
}else{
return XForwardedFor;
}
}
XForwardedFor = XRealIp;
if(StringUtils.isNotEmpty(XForwardedFor) && !"unKnown".equalsIgnoreCase(XForwardedFor)){
return XForwardedFor;
}
if (StringUtils.isBlank(XForwardedFor) || "unknown".equalsIgnoreCase(XForwardedFor)) {
XForwardedFor = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(XForwardedFor) || "unknown".equalsIgnoreCase(XForwardedFor)) {
XForwardedFor = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(XForwardedFor) || "unknown".equalsIgnoreCase(XForwardedFor)) {
XForwardedFor = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isBlank(XForwardedFor) || "unknown".equalsIgnoreCase(XForwardedFor)) {
XForwardedFor = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isBlank(XForwardedFor) || "unknown".equalsIgnoreCase(XForwardedFor)) {
XForwardedFor = request.getRemoteAddr();
}
return XForwardedFor;
}
}