1. 程式人生 > >ngxin做http強制跳轉https,接口的POST請求變成了GET

ngxin做http強制跳轉https,接口的POST請求變成了GET

nginx http https ssl postget

公司準備將 http 換成 https,就需要 http 強制跳轉到 https。這個在網上搜了下,基本總結下

在 server 裏面配置 rewrite ^(.*)$ https://$host$1 permanent;

或者在server裏面配置 return 301 https://$server_name$request_uri;

或者在server裏面配 if,這裏指的是需要配置多個域名

if ($host ~* "^wangshibo.com$") { rewrite ^/(.*)$ https://dev.wangshibo.com/ permanent;}

或者在server裏面配置

error_page 497 https://$host$uri?$args;

基本就上面這幾種方法,網站訪問是沒問題的,跳轉也是ok的


配置成功之後,準備把APP接口的地址也換成https,這就遇到問題了

排查原因發現,首先GET請求是可以收到信息的,POST傳參過去是沒有信息,我在nginx日誌裏面配置了$request_body,日誌裏面發現確實是沒有帶參數進來,查看日誌的前面,POST卻變成了GET。找到了問題的關鍵

通過網上查資料,發現是由於 301引起的。換成307問題解決。

301 Moved Permanently
被請求的資源已永久移動到新位置,並且將來任何對此資源的引用都應該使用本響應返回的若幹個 URI 之一


307 Temporary Redirect
請求的資源現在臨時從不同的URI 響應請求。由於這樣的重定向是臨時的,客戶端應當繼續向原有地址發送以後的請求

從上面我們可以看出,301跳轉是永久重定向,而307是臨時重定向。這就是301跳轉與307跳轉兩者之間的區別


上面可能看的不是很懂,簡單直白的表述一下區別:


return 307 https://$server_name$request_uri;


307:對於 POST 請求,表示請求還沒有被處理,客戶端應該向 Location 裏的 URI 重新發起 POST 請求

換成 307 狀態碼即可強制要求不能更改之前的方法。


下面配置80與443共存:

需要配置在一個server裏面,443端口後面加ssl。註釋掉 ssl on;,具體如下:

server{
        listen 80;
        listen 443 ssl;
        server_name testapp.***.com;
        root /data/vhost/test-app;
        index index.html index.htm index.shtml index.php;
        
        #ssl on;
        ssl_certificate      /usr/local/nginx/https/***.crt;
        ssl_certificate_key  /usr/local/nginx/https/***.key;
        ssl_session_timeout  5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
        ssl_prefer_server_ciphers on
        ssl_session_cache shared:SSL:10m;
        error_page  404     /404.html;
    
        location ~ [^/]\.php(/|$) {
            fastcgi_index index.php;
            include fastcgi.conf;
            fastcgi_pass   127.0.0.1:9000;
            #include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        }
       access_log  /data/logs/nginx/access.log  access;
       error_log  /data/logs/nginx/error.log  crit;
}


兩個server的寫法:

server{
        listen 80;
        server_name testapp.***.com;
        rewrite ^(.*) https://$server_name$1 permanent;
}

server{
        listen 443;
        server_name testapp.***.com;
        root /data/vhost/test-app;
        index index.html index.htm index.shtml index.php;
        
        ssl on;
        ssl_certificate      /usr/local/nginx/https/***.crt;
        ssl_certificate_key  /usr/local/nginx/https/***.key;
        ssl_session_timeout  5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
        ssl_prefer_server_ciphers on
        ssl_session_cache shared:SSL:10m;
        error_page  404     /404.html;
    
        location ~ [^/]\.php(/|$) {
            fastcgi_index index.php;
            include fastcgi.conf;
            fastcgi_pass   127.0.0.1:9000;
            #include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        }
       access_log  /data/logs/nginx/access.log  access;
       error_log  /data/logs/nginx/error.log  crit;
}

獻上ssl優化,以下可以根據業務來使用,不必全部配置,一般配置紅色的部分就行了

ssl on;

ssl_certificate /usr/local/https/www.localhost.com.crt;ssl_certificate_key /usr/local/https/www.localhost.com.key;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;  #只允許TLS協議
ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;#加密套件,這裏用了CloudFlare's Internet facing SSL cipher configurationssl_prefer_server_ciphers on;  #由服務器協商最佳的加密算法ssl_session_cache builtin:1000 shared:SSL:10m;
#Session Cache,將Session緩存到服務器,這可能會占用更多的服務器資源ssl_session_tickets on;  #開啟瀏覽器的Session Ticket緩存ssl_session_timeout 10m;  #SSL session過期時間ssl_stapling on; 
#OCSP Stapling開啟,OCSP是用於在線查詢證書吊銷情況的服務,使用OCSP Stapling能將證書有效狀態的信息緩存到服務器,提高TLS握手速度ssl_stapling_verify on;  #OCSP Stapling驗證開啟resolver 8.8.8.8 8.8.4.4 valid=300s;  #用於查詢OCSP服務器的DNSresolver_timeout 5s;  #查詢域名超時時間



ngxin做http強制跳轉https,接口的POST請求變成了GET