Search code examples
laravel.htaccesshttp-redirectmod-rewritehttps

Redirect http to https in laravel 5.2


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]


Solution

  • 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.)