Laravel 5 - htaccess HTTPS redirect on post routes doesn't work.

后端 未结 1 1504
渐次进展
渐次进展 2020-12-21 17:27

I have an application built with Laravel 5 acting as an API. I have the following in my .htaccess file to redirect all routes to https:

  RewriteEngine On

          


        
1条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-21 18:23

    In order to force https, your RewriteRule is required to force an external redirect. In the case of your rule, you're forcing a 301 redirect (R=301). Most browsers and clients are designed to automatically follow redirects, but they (incorrectly) do so with a GET request.

    So, when a client sends a POST request with data to http://example.com/route, your server responds with a 301 redirect to https://example.com/route, and then the client makes a GET request without the data to the new URL. As you can see, you can't just change your routes to accept GET requests as well, because the data sent in the original POST request will be dropped.

    One option would be to add a rewrite condition to not redirect POST requests:

    # Force SSL
    RewriteCond %{HTTPS} !=on
    RewriteCond %{REQUEST_METHOD} !=POST
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    

    However, this pretty much defeats the purpose of what you're attempting to accomplish. This whole concept is to force https everywhere. It would be silly to enforce it everywhere except when POSTing data to your application.

    Another possible option would be to change your 301 redirect to a 307 redirect. Even though clients aren't supposed to change the request method for 301/302 redirects, most clients do due to ambiguity in the specs and existing functionality. Because of this, 307 was added with the specific idea that if this status code is used, the request method MUST NOT be changed. However, 307 is classified as a "temporary redirect", so it won't be cached and may affect your SEO. Additionally, this status was added in the HTTP/1.1 spec, so you may run into some clients that don't know how to process a 307.

    Your best option is probably just to reject non-secure POST requests. Or, redirect them to an error page explaining you don't accept non-secure POST requests.

    RewriteEngine On
    
    # Forbid non-secure POSTs
    RewriteCond %{HTTPS} !=on
    RewriteCond %{REQUEST_METHOD} =POST
    RewriteRule ^ / [F,L]
    
    # Force SSL
    RewriteCond %{HTTPS} !=on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    

    0 讨论(0)
提交回复
热议问题