Nginx反向代理后应用程序获取客户端真实IP
Nginx反向代理后,Servlet应用通过request.getRemoteAddr()取到的IP是Nginx的IP地址,并非客户端真实IP,通过request.getRequestURL()获取的域名、协议、端口都是Nginx访问Web应用时的域名、协议、端口,而非客户端浏览器地址栏上的真实域名、协议、端口。
Nginx的反向代理实际上是客户端和真实的应用服务器之间的一个桥梁,客户端(一般是浏览器)访问Nginx服务器,Nginx再去访问Web应用服务器。对于Web应用来说,这次HTTP请求的客户端是Nginx而非真实的客户端浏览器,如果不做特殊处理的话,Web应用会把Nginx当作请求的客户端,获取到的客户端信息就是Nginx的一些信息。
解决这个问题要从两个方面来解决: 
1. 由于Nginx是代理服务器,所有客户端请求都从Nginx转发到Tomcat,如果Nginx不把客户端真实IP、域名、协议、端口告诉Tomcat,那么Tomcat应用是永远不会知道这些信息的,所以需要Nginx配置一些HTTP Header来将这些信息告诉被代理的Tomcat; 
2. Tomcat这一端,不能再傻乎乎的获取直接和它连接的客户端(也就是Nginx)的信息,而是要从Nginx传递过来的HTTP Header中获取客户端信息。
修改Nginx配置:
-- 在location/ 增加以下属性:
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
示例:
     location /masl {
         proxy_pass http://asl_server/masl;
             proxy_redirect off;
 7             proxy_set_header X-Forwarded-Proto $scheme;
 8             proxy_set_header Host $host:$server_port;
10             proxy_set_header X-Real-IP $remote_addr;
11             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             client_max_body_size 100m;
             client_body_buffer_size 128k;
             proxy_connect_timeout 90;
             proxy_send_timeout 90;
             proxy_read_timeout 90;
             proxy_buffer_size 4k;
             proxy_buffers 4 32k;
             proxy_busy_buffers_size 64k;
             proxy_temp_file_write_size 256k;
         }
解释以下上面的配置,以上配置是在Nginx反向代理的时候,添加一些请求Header。 
1. Host包含客户端真实的域名和端口号; 
2. X-Forwarded-Proto表示客户端真实的协议(http还是https); 
3. X-Real-IP表示客户端真实的IP; 
4. X-Forwarded-For这个Header和X-Real-IP类似,但它在多层代理时会包含真实客户端及中间每个代理服务器的IP。
配置到这一步后,还不能彻底解决问题。tomcat也需要配置
如果你在网上搜索“Java如何获取客户端真实IP”,搜索到的解决方案大多是通过获取HTTP请求头request.getHeader("X-Forwarded-For")或request.getHeader("X-Real-IP")来实现,也就是上面在Nginx上配置的Header,这种方案获取的结果的确是正确的,但觉得并不优雅。因为既然Servlet API提供了request.getRemoteAddr()方法获取客户端IP,那么无论有没有用反向代理对于代码编写者来说应该是透明的。下面介绍一种更加优雅的方式。
使用Tomcat作为应用服务器,可以通过配置Tomcat的server.xml文件,在Host元素内最后加入:即可
<Valve className="org.apache.catalina.valves.RemoteIpValve" />
Nginx反向代理后应用程序获取客户端真实IP的更多相关文章
- Nginx反向代理后,java获取客户端真实IP地址
		
一般情况下,java获取客户端IP地址的方法为request.getRemoteAddr();但这只是在没有网关或者代理的情况下,如果客户端将请求发送到nginx,再由nginx进行反向代理到目标服务 ...
 - nginx 代理模式下,获取客户端真实IP
		
最近做博友推荐,发现个小问题,用$_SERVER['REMOTE_ADDR'];得到的都是服务器的地址192.168.96.52,搜索了一下,发现问题,改为$_SERVER['HTTP_X_REAL_ ...
 - nginx反向代理后应用程序如何获取客户端真实IP
		
每个location中增加配置: proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_se ...
 - 在有nginx做反向代理时候,如何获取用户真实Ip信息
		
在获取用户的Ip地址时,不一定可以获取到用户真实的地址信息,这要看代理服务器的类型,代理服务器有普通匿名代理服务器,高匿代理服务器,像这种情况很难获取到用户真实的Ip地址 假如用户没有使用匿名代理服务 ...
 - JAVA获取客户端请求的当前网络ip地址(附:Nginx反向代理后获取客户端请求的真实IP)
		
1. JAVA获取客户端请求的当前网络ip地址: /** * 获取客户端请求的当前网络ip * @param request * @return */ public static String get ...
 - Nginx负载均衡反向代理 后端Nginx获取客户端真实IP
		
Nginx 反向代理后,后端Nginx服务器无法正常获取客户端的真实IP nginx通过http_realip_module模块来实现的这需要重新编译,如果提前编译好了就无需重新编译了1,重新编译ng ...
 - nginx反向代理后端web服务器记录客户端ip地址
		
nginx在做反向代理的时候,后端的nginx web服务器log中记录的地址都是反向代理服务器的地址,无法查看客户端访问的真实ip. 在反向代理服务器的nginx.conf配置文件中进行配置. lo ...
 - nginx反向代理后getRequestURL会出现问题
		
nginx反向代理后getRequestURL会出现问题 http://huangqiqing123.iteye.com/blog/1895192
 - 【Nginx】如何获取客户端真实IP、域名、协议、端口?看这一篇就够了!
		
写在前面 Nginx最为最受欢迎的反向代理和负载均衡服务器,被广泛的应用于互联网项目中.这不仅仅是因为Nginx本身比较轻量,更多的是得益于Nginx的高性能特性,以及支持插件化开发,为此,很多开发者 ...
 
随机推荐
- js excel导出功能
			
<html> <head> <p style="font-size: 20px;color: red;">使用a标签方式将json导出csv文件 ...
 - ajax获取json 格式绑定下拉框
			
[{"ClassID":"1","ClassName":"C#","CategorysID":&qu ...
 - vue.js 简介
			
Vue.js是什么 Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核心库只关注视图层 ...
 - HttpServletResponse 返回的json数据不是json字符串,而是json对象
			
今天在改一个bug 情况: 在spring boot中写了一个类Result ,用来统一封装 各个API响应结果 , 其中重写了toString()方法来返回 json字符串 . 在正常情况下,从其它 ...
 - puppet 3+Unicorn+Nginx安装配置
			
puppet 3+Unicorn+Nginx安装配置 2014-08-15 10:58 酒瓶不倒 酒瓶不倒的博客 字号:T | T 一键收藏,随时查看,分享好友! Unicorn 效率要比 Webri ...
 - python--UUID唯一标识符
			
UUID: 通用唯一标识符 ( Universally Unique Identifier ), 对于所有的UUID它可以保证在空间和时间上的唯一性. 它是通过MAC地址, 时间戳, 命名空间, 随机 ...
 - ansible变量定义
			
一./etc/ansible/hosts [webServers] 192.168.2.200 http_port=8009 [web]web1web2 [db]db1db2 [app:childre ...
 - android adb 命令发送 keyevent
			
使用Adb shell command直接送key event給Android adb shell input keyevent 7 # for key '0' adb shell input key ...
 - python拼音库pypinyin库详解
			
# -*- coding: utf-8 -*- # @Author : FELIX # @Date : 2018/6/30 9:20 from pypinyin import pinyin, lazy ...
 - 欧拉函数(线性筛)(超好Dong)
			
欧拉函数:对于一个正整数n,小于n且和n互质的正整数(包括1)的个数,记作φ(n) . #include <bits/stdc++.h> using namespace std; cons ...