Redirect http to https in laravel 5.2

10,084

Solution 1

Your HTTP to HTTPS redirect needs to go near the top of your .htaccess file, immediately after the RewriteEngine directive and, importantly, before the Laravel front controller.

As a general rule, external redirects should always go before internal rewrites.

The front controller catches all requests (or rather requests that don't map to a physical file or directory) and rewrites these to index.php (that ultimately handles the routeing). The problem is that your HTTP to HTTPS redirect occurs later and converts the now rewritten URL into an external redirect to index.php.

Likewise, your # Handle Authorization Header block should also go before the front controller (ideally). (It will work in its current state, in per-directory .htaccess files, due to the looping nature of .htaccess files, but if you moved these directives to the server config it would fail.)

Solution 2

RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

Add the above two lines just below RewriteEngine On in your .htaccess file. It will automatically redirect any traffic destined for http: to https:

Finally, your .htaccess file will look like the following

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Redirect to https
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>
Share:
10,084
Juan Lopez
Author by

Juan Lopez

Updated on June 04, 2022

Comments

  • Juan Lopez
    Juan Lopez almost 2 years

    I have a Laravel 5.2 project. Recently, I installed an SSL certificate on my website so when I type https://example.com in the browser it works but when I write example.com, it connects by HTTP.

    To fix that, I added these lines to my .htaccess file:

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

    After that, when I type example.com, the browser redirects me to https://example.com. That's perfect.

    The problem is when I try to access the URL http://example.com/download/get/book/volume2, it doesn't redirect me to HTTPS. It redirects me to the index page. If I add the s of https in the URL it works fine but I need the app to redirect me from HTTP to HTTPS.

    The route in routes file:

    Route::get('download/get/book/{book}'
    

    That route opens a PDF file that I have in privates/storage folder in the browser's tab.

    EDIT:

    My .htaccess file:

    <IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>
    
    RewriteEngine On
    
    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)/$ /$1 [L,R=301]
    
    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    
    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    
    # require SSL 
    RewriteCond %{HTTPS} !=on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    

  • Juan Lopez
    Juan Lopez almost 7 years
    Thanks for your aswer. I made the changes you said but it still doesn't work.
  • MrWhite
    MrWhite almost 7 years
    Make sure you clear your browser cache before testing. The earlier (erroneous) 301s will have been cached by the browser. (It is often preferable to test with 302s for this reason - to avoid the cache.)
  • Sundar
    Sundar almost 4 years
    This solution is working for me. # Redirect to https RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
  • Loganathan Natarajan
    Loganathan Natarajan over 3 years
    it worked to me fine in my shared hosting server
  • MrWhite
    MrWhite over 2 years
    This doesn't add anything that the existing answer does not already address. In fact, the subtle changes you've made to the HTTP to HTTPS directive are incorrect. For some reason, you've changed the 301 (permanent) redirect to an implied 302 (temporary) redirect. This is fine for testing, but the redirect should be a 301 in production. You've also changed the RewriteRule pattern from ^ to (.*) - why? ^ is much more efficient here. The regex (.*) unnecessarily traverses the entire URL-path and captures a backreference, which is not being used in the directive.