# 问题

Nginx 反向代理之后,Tomcat 应用通过 request.getHeader("host") 取到的是 Nginx 的 host,并非客户端浏览器地址栏上的真实域名。

例如在某一台服务器上,Tomcat 的端口号为 8080,Nginx 的端口号为 80,Nginx 反向代理 8080 端口。

server {
    listen 80;
    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

在另一台机器上用浏览器打开 http://haha/test 访问 Tomcat 下的应用,获取客户端域名。

System.out.println(request.getHeader("host"));

结果是:

localhost:8080

# 问题产生的原因

Nginx 的反向代理实际上是客户端和真是的应用服务器之间的一个桥梁,客户端(一般是浏览器)访问 Nginx 服务器,Nginx 再去访问 Web 应用服务器。对于 Web 应用来说,这次 HTTP 请求的客户端是 Nginx 而非真实的客户端浏览器,如果不做特殊处理的话,Web 应用会把 Nginx 当做请求的客户端,获取到的客户端信息就是 Nginx 的一些信息。

# 问题解决

  1. Nginx 配置 HTTP Header。Host 包含客户端真实的域名和端口号

    proxy_set_header Host $http_host;
    
  2. Tomcat 从 Nginx 传递过来的 HTTP Header 中获取客户端信息。

    <Valve className="org.apache.catalina.valves.RemoteIpValve" />