1. 前言
现有的项目中,一般都不会把应用真实的访问路径暴露给浏览器,在浏览器和服务端应用之间,会使用 Nginx 进行反向代理,这样可以对服务端应用的安全性和扩展性进行控制。
使用 Nginx 进行反向代理之后,如何在服务端应用中获取到真实的访问IP和端口呢?我们对 Java Web 应用进行配置测试。
2. 平台
- Java Web + Tomcat
- Spring Boot
3. Nginx 配置
server {
listen 80;
server_name xx.xxx.xxx.xxx;
location / {
proxy_pass http://localhost:8080/;
# Host包含客户端真实的域名和端口号
proxy_set_header Host $host;
# X-Real-IP表示客户端真实的IP
proxy_set_header X-Real-IP $remote_addr;
# X-Forwarded-For这个Header和X-Real-IP类似,
# 但它在多层代理时会包含真实客户端及中间每个代理服务器的IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# X-Forwarded-Proto表示客户端真实的协议(http还是https)
proxy_set_header X-Forwarded-Proto $scheme;
}
}
4. Java Web + Tomcat
使用Tomcat作为应用服务器,可以通过配置Tomcat的server.xml文件,在Host元素内最后加入:即可
<Valve className="org.apache.catalina.valves.RemoteIpValve" />
5. Spring Boot
我们以 YML 配置文件为例:
server:
port: 8080
servlet:
context-path: /
# 下面的配置为使spring boot获取得到的访问的真实IP
use-forward-headers: true
tomcat:
remote-ip-header: X-Real-IP
protocol-header: X-Forwarded-Proto
6. Java 应用中获取IP
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String remoteHost = request.getRemoteHost();