精华帖 (7) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-06-13
melin 写道 ServletRequestContextBuilder 中获取IP方法 request.getRemoteAddr();
在有代理的情况下,获取不到真实的IP。 public static String getRemoteIP(HttpServletRequest request) { String remoteIP = request.getHeader("X-Real-IP"); if (!StringUtils.hasText(remoteIP)) { remoteIP = request.getRemoteAddr(); } return remoteIP; } 谢谢,我马上改下,看了另外一位兄弟的帖子更全些http://ytfei.iteye.com/blog/811868: 引用 服务器上运行nginx 转发请求到 tomcat 8080 的jsp
获取到的信息 request.getHeader("x-real-ip");= 58.x.x.x request.getHeader("x-forwarded-for");=10.15.x.x, 58.x.x.x request.getHeader("Proxy-Client-IP");=null request.getHeader("WL-Proxy-Client-IP");=null request.getRemoteAddr();=202.x.x.x 直接访问 tomcat 8080 的jsp request.getHeader("x-real-ip");= null request.getHeader("x-forwarded-for");=10.15.x.x request.getHeader("Proxy-Client-IP");=null request.getHeader("WL-Proxy-Client-IP");=null request.getRemoteAddr();=58.x.x.x 客户端浏览器是有用代理的 58.x.x.x 是代理的公网IP。10.15.x.x 是客户端的局域网IP。 202.x.x.x 是tomcat服务器的IP 因此如果想获取远程用户上网的IP,只要获取 x-real-ip 如果 x-real-ip 为空,直接获取 request.getRemoteAddr(); 如果使用apache反向代理则参见http://www.blogjava.net/kingmove/articles/266606.html: 引用 apache反向代理,如何获取用户真实IP 很多时候项目都需要获取用户的真实IP进行一些分析或者权限过滤,一般情况下通过request.getRemoteAddr()就可取得客户端的IP地址,但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。 如果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为http://www.xxx.com/ 的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。 经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。 原来如此,我们的项目中正好是有前置apache,将一些请求转发给后端的weblogic,看来就是这样导致的咯。 给出一份还算靠谱的代码,如下: Java代码 public String getIpAddr(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(); } return ip; } 如果有人遇到类似问题,请多加留意,呵呵。 PS:可是,如果通过了多级反向代理的话,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 |
|
返回顶楼 | |
发表时间:2012-06-13
最后修改:2012-06-13
现在开源出来的代码感觉有问题
没有地方调用DefaultRopContext public void addServiceMethod(String methodName, String version, ServiceMethodHandler serviceMethodHandler) {方法, 应该用BeanPostProcessor类? 开源的代码中没有 |
|
返回顶楼 | |
发表时间:2012-06-13
melin 写道 现在开源出来的代码感觉有问题
没有地方调用DefaultRopContext public void addServiceMethod(String methodName, String version, ServiceMethodHandler serviceMethodHandler) {方法, 应该用BeanPostProcessor类? 开源的代码中没有 有啊,DefaultRopContext本身的registerFromContext()方法就调用这个方法进行处理方法注册的,这个方法还允许你动态在运行期注册一个服务方法。 |
|
返回顶楼 | |
发表时间:2012-06-13
stamen 写道 melin 写道 现在开源出来的代码感觉有问题
没有地方调用DefaultRopContext public void addServiceMethod(String methodName, String version, ServiceMethodHandler serviceMethodHandler) {方法, 应该用BeanPostProcessor类? 开源的代码中没有 有啊,DefaultRopContext本身的registerFromContext()方法就调用这个方法进行处理方法注册的,这个方法还允许你动态在运行期注册一个服务方法。 哦,sorry! |
|
返回顶楼 | |
发表时间:2012-06-13
melin 写道 ServletRequestContextBuilder 中获取IP方法 request.getRemoteAddr();
在有代理的情况下,获取不到真实的IP。 public static String getRemoteIP(HttpServletRequest request) { String remoteIP = request.getHeader("X-Real-IP"); if (!StringUtils.hasText(remoteIP)) { remoteIP = request.getRemoteAddr(); } return remoteIP; } 我已经更改了,参照你的实现,我的实现版本是: private String getRemoteAddr(HttpServletRequest request) { String remoteIp = request.getHeader(X_REAL_IP); //nginx反向代理 if (StringUtils.hasText(remoteIp)) { return remoteIp; } else { remoteIp = request.getHeader(X_FORWARDED_FOR);//apache反射代理 if (StringUtils.hasText(remoteIp)) { String[] ips = remoteIp.split(","); for (String ip : ips) { if (!"null".equalsIgnoreCase(ip)) { return ip; } } } return request.getRemoteAddr(); } } 添加了代理是apache的情况,代码已经提交 Commit 信息: 引用 fix the bug of get Remoate client ip from the nigix or apache proxy the backend server(thanks for melin[bsli@xxx.com.cn]). |
|
返回顶楼 | |
发表时间:2012-06-14
lz,UserRestService服务类应该会直接调用业务逻辑接口来完成具体的业务请求吧?
目前demo都是直接返回一个response |
|
返回顶楼 | |
发表时间:2012-06-14
kelloKitty 写道 lz,UserRestService服务类应该会直接调用业务逻辑接口来完成具体的业务请求吧?
目前demo都是直接返回一个response 可以直接在UserRestService中完成业务,也可以调用其它Service,这看你自己设计了(一般是调用其它的Service) |
|
返回顶楼 | |
发表时间:2012-06-14
学习了啊,用起来挺方便的
|
|
返回顶楼 | |
发表时间:2012-06-14
melin兄昨天给我提交了一份代码(发短信给我),是关于Rop会话实现的,我今天看了一下,感觉实现得非常好,我会尽快将其整合到Rop中,也欢迎大家贡献Rop的代码,一起把这个开源软件做好做强!
大家可以将代码更改 或新的功能 通过站内短信,或发邮件给我,我的邮箱是:itstamen@qq.com 欢迎加入Rop群组:http://rop.group.iteye.com/ 现开放加入,不用审核。 |
|
返回顶楼 | |