What is the best way to force https?

SilverStripe 4

Is it possible to force https with htacess?

My host told me to use this:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1[R=301,L]

But I’m not quite sure how to write this to play nice with my existing htaccess, which is:

RewriteEngine On
RewriteRule ^(.*)$ public/$1

Would it be this?

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/public/$1[R=301,L]

as @JonoM said, you need to put this in the .htaccessof your webroot, which might be /public/.htaccess if you’re using the public folder.

I put this at the very beginning of my .htaccess:

RewriteCond %{HTTP_HOST} ^my-project\.at$ [OR]
RewriteCond %{HTTP_HOST} ^www.my-project\.at$
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://www.my-project.at/$1 [R=301,L]

### SILVERSTRIPE START ###

With the domain in the rules I can also use it for projects with more domains, e.g. when using Subsites module.

When we’re already on https it skips that section and goes on to the standard SilverStripe definitions.

1 Like

I think you’ll find the more important .htaccess file is in your public folder. So you can probably leave the .htaccess file in your project root untouched, and add the directives your host gave you to the top of your /public/.htaccess file.

1 Like

Putting the rules at the beginning of public/.htaccess didn’t work. To get it working, I added the rules directly before the last SilverStripe rewrite rules.

# Force HTTPS Rules
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

# Process through SilverStripe if no file with the requested name exists.
# Pass through the original path as a query parameter, and retain the existing parameters.
# Try finding framework in the vendor folder first
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php

Is there a reason this would be better than just using Director::forceHttps() ?

1 Like

Because this happens at the server-level, making it more efficient, so you aren’t having to load the PHP interpreter, load the SilverStripe framework, etc. just to redirect the user to the secure version.

1 Like