nginx 配置Https强转和Cross跨域配置撞车遇到的坑

一、背景说明
项目中Https强转逻辑是在nginx层面配置的,Cross跨域逻辑处理是在项目的Java代码层面处理的。
向服务器发起Http跨域请求时,出现Cross跨域逻辑处理失效问题
nginx 中Https 强转配置,如下所示:

if ($server_port = 80 ) {
   rewrite ^(.*)$  https://$host$1 permanent;
}

Cross跨域逻辑处理层,代码如下所示:

String originUrl = request.getHeader("origin");//请求的地址
if (StringUtils.isNotEmpty(originUrl)){
       if (originUrl.endsWith("test.com")){
           response.setHeader("Access-Control-Allow-Origin", originUrl);
           response.setHeader("Access-Control-Allow-Credentials", "true");
           response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
           response.setHeader("Access-Control-Max-Age", "1800");//30分钟
           response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,frLo");
      }
      if (request.getMethod().equalsIgnoreCase(HttpMethod.OPTIONS.name())) {   
           response.setStatus(200);
           return false;
     }
}

二、问题描述

1)例如:在sun.test.com系统中,使用JS脚本发起Ajax请求,向my.timer.com服务器发起Http请求,my.timer.com服务器中配置了以上的Https强转和Cross逻辑处理代码。
2)my.timer.com 服务器的nginx收到Http请求后,会执行Https强转,然后发起重定向rewrite Https请求,此时由于发起了重定向请求导致原跨域请求header中的origin 参数丢失
注:rewrite 和 return 301 https://$host$request_uri; 都会导致header 中的orgin参数丢失,因为两种方式都是发起重定向请求
3) my.timer.com 服务器再次收到第2步重定向后的Https请求,由于header中的origin参数丢失,最终导致后端java  Cross跨域处理逻辑失效,由于Cross 是否跨域请求都是借助header中的origin参数来处理的

三、问题尝试解决

1)考虑在nginx中 rewrite之前 使用   add_header 'Origin' $http_origin;  添加header,无法解决问题,因为rewrite 是重定向请求,add_header 无法生效

2)将Cross 跨域逻辑处理转移到nginx中配置如下所示:

set $cors "false";
if ($http_origin ~* "(test.com)") {
      set $cors "true0";
}
if ($request_method = 'OPTIONS') {
    set $cors "true1";
}
if ($cors = "true0") {
      add_header 'Access-Control-Allow-Origin' "$http_origin";
      add_header 'Access-Control-Allow-Credentials' 'true';
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
      add_header 'Access-Control-Max-Age' 1728000;
}
if ($cors = "true1") {
  add_header 'Access-Control-Allow-Origin' "$http_origin";
  add_header 'Access-Control-Allow-Credentials' 'true';
  add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
  add_header 'Access-Control-Allow-Headers' 'Origin,X-Requested-With,Content-Type,Accept,frLo';
  add_header 'Access-Control-Max-Age' 1728000;
  return 200;
}
if ($server_port = 80 ) {
	 rewrite ^(.*)$  https://$host$1 permanent;
}

还是无法解决以上问题

四、解决方案

未找到完美解决方案,只能让sun.test.com系统中发起跨域Ajax请求时,默认使用Https协议请求服务器,避开服务的Http请求强转。

猜你喜欢

转载自blog.csdn.net/TimerBin/article/details/97282746
今日推荐