Nginx配置http访问跳转同域名的https

背景:有一个需求 需要访问http的站点全部重定向到https的站点,例如: 访问http://xxx.abc.tiantianjiaban.icu 跳转到  https://xxx.abc.tiantianjiaban.icu 这个地址。

 

问题一:跳转重定向之后,域名不正确,域名当中带有 %2A 

起初配置的nginx如下:

    server {
        listen       80;
        server_name  *.abc.tiantianjiaban.icu;
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        
        }
        rewrite ^(.*) https://$server_name$1 permanent;

    }

    server {
        listen      443 ssl;
        server_name  *.abc.tiantianjiaban.icu;

        ssl_certificate      /home/cms/nginx/ssl/tiantianjiaban.pem;
        ssl_certificate_key  /home/cms/nginx/ssl/tiantianjiaban.key;
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  10m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            include /home/cms/nginx/conf/nginx_cors;
            root /home/tiantianjiaban/static/;
            error_page 404 = /index.html;
            try_files $uri $uri/ /index.html;
        }

    }

 

1、域名配置的是 *.abc.tiantianjiaban.icu  本意是想让 三级域名 xxx.abc.tiantianjiaban.icu 都能路由到nginx服务器上。

2、rewrite ^(.*) https://$server_name$1 permanent;  使用重定向的方式转到https的域名上

结果访问结果出现一个问题:

例如:访问 http://xxx.abc.tiantianjiaban.icu  跳转的结果是  https://%2A.abc.tiantianjiaban.icu 

看到%2A,我第一个想到就是URL被Encode了,的确 * 在encode之后是2A,原因就在于 使用但是 $server_name 这个变量。

查阅了一些资料之后:找到了一种解决方式,就是把 重定向那句代码修正为如下:

rewrite ^(.*) https://$host$request_uri permanent;

为了更好的展示为什么要修正为这个,我修改了nginx的access.log打印的日志:

    log_format  main  '$clientRealIp -> $upstream_addr [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer"'
                      '"$upstream_response_time"'
                      'server_name ="$server_name" host="$host" http_host="$http_host" hostname="$hostname" request_uri="$request_uri" uri="$uri"';

我分别打印了如下的nginx变量

$server_name 、$host、  $http_host、  $hostname、  $request_uri、  $uri

然后访问刚刚出现%2A的地址:

10.17.84.23 -> - [09/Feb/2021:11:38:31 +0800] "GET / HTTP/1.1" 301 178 "-""-"
server_name ="*.abc.tiantianjiaban.icu" host="abcd.abc.tiantianjiaban.icu" http_host="abcd.abc.tiantianjiaban.icu" hostname="server001" request_uri="/" uri="/"
10.17.84.23 -> - [09/Feb/2021:11:39:29 +0800] "GET /login?Type=test HTTP/1.1" 301 178 "-""-"
server_name ="*.abc.tiantianjiaban.icu" host="abcde.abc.tiantianjiaban.icu" http_host="abcde.abc.tiantianjiaban.icu" hostname="server001" request_uri="/login?Type=test" uri="/login"

分别请求:不带具体路径和带具体路径参数的地址

http://abcd.abc.tiantianjiaban.icu/

http://abcde.abc.tiantianjiaban.icu/login?Type=test

可以看到:

1、server_name 是带有 * 符号的,所以我猜想在进行域名转换的时候,如果使用 rewrite ,这个*号就被URLEncode了。

2、host 这个就是我们使用的具体的域名,所以也就是为什么在rewrite的是要使用 $host

3、然后看一下 request_uri 和 uri ,发现uri是不带有参数,如果想要跳转之后也带着参数,就要使用 request_uri 

 

问题二、跳转之后参数的传递。使用request_uri还是uri

上一个问题,我简单打印出来了 request_uri  和 uri 这两个值,发现request_uri是带有参数的,而uri不带有参数。

但是如果按照上一步配置了, 还会遇到下面的问题

rewrite ^(.*) https://$host$request_uri permanent;

例如:我们请求  http://aaaaa.abc.tiantianjiaban.icu/login?Type=test 实际上跳转的地址是  https://aaaaa.abc.tiantianjiaban.icu/login?Type=test?%3Ftype

问题出在哪里呢?如果把 request_uri 改成 uri ,再试一下

rewrite ^(.*) https://$host$uri permanent;

惊奇的发现,就正确了   https://aaaaa.abc.tiantianjiaban.icu/login?Type=test 。 所以还是要用uri。

但是如果我们想要忽略这个后面的参数,应该如何做,例如

http://abcde.abc.tiantianjiaban.icu/login?Type=test  ------>   https://abcde.abc.tiantianjiaban.icu/login

Nginx当中我们可以在$uri后面加上一个 【?】符号

rewrite ^(.*) https://$host$uri? permanent;

 

查看一下这两个参数的区别(官方说明):

$request_uri

This variable is equal to the complete initial URI together with the arguments;

这个变量是完整的带有参数的初始URI

$uri

This variable is equal to current URI in the request, it can differ from initial, for example by internal redirects, or with the use of index it is file with internal redirects.

这个变量是当前请求中的URI,它或许和初始的URI不同,例如 内部的重定向或者内部的索引。

 

我在其他人文章中找到了一些依据: https://www.cnblogs.com/xiaoleiel/p/8308492.html  这里讲述了一些关于重定向的问题。

总结就是 Nginx默认情况重定向都是带着参数的,如果我们是用的是 $request_uri 实际上相当于在原来的基础上多拼接了一次参数。为了验证我们分别截取了 使用request_uri、uri、以及uri? 的重定向日志。

Request_URI
10.17.84.23 -> - [09/Feb/2021:14:00:36 +0800] "GET /?type=test HTTP/1.1" 301 178 "-""-"[scheme="http" ] [host="abcd.abc.tiantianjiaban.icu" ]  [request_uri="/login?type=test" ] [uri="/login" ] 
10.17.84.23 -> - [09/Feb/2021:14:00:41 +0800] "GET /?type=test?type=test HTTP/1.1" 200 518 "-""-"[scheme="https" ] [host="abcd.abc.tiantianjiaban.icu" ] [request_uri="/login?type=test?type=test" ] [uri="/index.html" ] 

URI
10.17.84.23 -> - [09/Feb/2021:14:10:11 +0800] "GET /login?type=test HTTP/1.1" 301 178 "-""-"[scheme="http" ][host="abcd.abc.tiantianjiaban.icu" ] [request_uri="/login?type=test" ] [uri="/login" ] 
10.17.84.23 -> - [09/Feb/2021:14:10:14 +0800] "GET /login?type=test HTTP/1.1" 200 518 "-""-"[scheme="https" ][host="abcd.abc.tiantianjiaban.icu" ] [request_uri="/login?type=test" ] [uri="/index.html" ] 

URI?
10.17.84.23 -> - [09/Feb/2021:13:48:05 +0800] "GET /login?type=test HTTP/1.1" 301 178 "-""-"[scheme="http" ] [host="abcd.abc.tiantianjiaban.icu" ]  [request_uri="/login?type=test" ] [uri="/login" ] 
10.17.84.23 -> - [09/Feb/2021:13:48:08 +0800] "GET /login HTTP/1.1" 200 518 "-""-"[scheme="https" ][host="bbba.capp-dev2.hikyun.com" ]  [request_uri="/login" ] [uri="/index.html" ] 

 

总结:所有如何要把相同域名的http站点请求重定向到https站点上,需要注意两个点:

1、如果域名不是确定的,例如我这边 *.xxx.yyy.com ,那么就不能使用 $server_name变量,要使用$host

2、如果需要参数传递,需要设置使用 $uri 而不是 $request_uri ,不需要参数需要使用 $uri?

 

posted @ 2021-02-09 11:52  奋斗的大橙子  阅读(1394)  评论(0)    收藏  举报