Nginx配置https访问,反向代理Tomcat无法正确获取schema和端口问题

分类: WEB开发 0人评论 selfly 1年前发布

问题

网站采用了 Nginx 反向代理 Tomcat 的方式来负载均衡。

Nginx使用https,默认端口443。Tomcat使用http,端口8080

结果今天后台操作停留时间过长session超时后,跳转到登录页面时出现无法访问错误。如图:

http_error

分析

可以看到,出错的原因应该是跳转的时候加上了web默认80端口,而https默认的端口并不是80,所以导致无法访问。

后台无session时跳转代码:

requestURL = HttpUtils.encodeUrl(requestURL);
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path
        + "/";
return basePath + "user/login?goUrl=" + requestURL;

代码跳转的是绝对路径,包括schema和port,问题应该就在这里。

经过调试发现获取到的request.getScheme()总是http而非实际的https,相应的request.getServerPort()也就成了80。

端口是80而非Tomcat本身的8080说明获取到的确实是nginx转发过来的请求,那schema为什么得不到呢?

解决

通过查找资料,发现nginx请求转发时必须设置proxy_set_header才能让被代理的tomcat获取到正确的客户端ip等信息。

但是之前已经设置过nginx的proxy_set_header,而获取ip等也毫无问题:

proxy_set_header X-Real-IP $remote_addr; 
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
proxy_set_header Host $http_host; 
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// $scheme://;
proxy_pass http://localhost:8080;#转向tomcat处理

上面有一行设置了proxy_redirect,所以浏览器地址栏的schema仍然是https.

接着查找资料,发现要传递schema,在Tomcat端也需要相应配置。

  
       
  

加上后,重启Tomcat,一切正常了!