As part of my series on migrating a site to support HTTPS we are finally at the step where we will implement the redirect that will ensure our users are always using the HTTPS site. In this article I will show how to implement this redirect using:
- Apache’s Mod Rewrite
- IIS Rewrite
In the examples and instructions below I am going to be using Apache on my local Mac development environment and Windows Server 2008 R2 with IIS 7.5 for the production environment. The code for the Apache Mod Rewrite implementation can also be used if you are using Helicon’s ISAPI Rewrite module for IIS. This makes it possible to use the same .htaccess file on both my development (Mac) and production (Windows) environment.
Apache Mod Rewrite
If you have not enabled the rewrite module for Apache, modify the httpd.conf configuration file by uncommenting the LoadModule line for the mod_rewrite extension.
My httpd.conf file is located at: /etc/apache2/httpd.conf.
$ cd /etc/apache2
$sudo nano httpd.conf
If you run the above code in terminal on your Mac you will be using the nano editor. Just scroll down until you see the following line. Remove the hash symbol ( # ) to enable the mod_rewrite extension.
The next step is to modify the .htaccess file in our web root, adding the following code to the file.
#Redirect to secure website
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} example\.com$
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The first condition is to ensure that the current request is not using https, then we check that the request is for our domain. Then we redirect all requests from the insecure site to the secure site using a permanent (301) redirect.
IIS Rewrite via URL Rewrite
We will first walk through creating the rewrite rule using the IIS Manager GUI. There are several steps, and in most cases it is easier and quicker to modify the web.config file by adding the rule definition in XML. We will take a look at the code later.
First, open IIS Manager and select the URL Rewrite feature, then click on the Add… link to add a new rule.
On the dialog that opens, select the Blank rule template.
Next, we will name the rule, set the matching pattern to match all requests, add a condition for only insecure requests, and then add a rewrite to redirect the user to the URL using HTTPS. As a side note, do not forget to name the rule, as it is required before you can apply your changes.
Here are the steps to create the new rule to redirect to HTTPS:
- Set name
- Click on Match section
- Set Pattern to: (.*)
- Click on Conditions section, then click the Add… button
- Set Condition input to: {HTTPS}
- Set Pattern to: ^OFF$
- Click OK
- Click on Actions section
- Set the Value to: https://{HTTP_HOST}/{R:1}
- Check Stop processing of subsequent rules
- Click Apply
IIS via web.config
The easier way to add the rewrite rule in IIS to redirect all insecure requests to use HTTPS is to modify the web.config file in your website root directory.
Here is my complete web.config file with only the Force HTTPS rewrite rule.
If you already have a web.config file with other settings, then simply paste in the <rule>
into your file.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<outboundRules>
<rule name="Force HTTPS" stopProcessing="true">
<match pattern="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Rewrite" value="https://{HTTP_HOST}/{R:1}"/>
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
Internal Links and Canonical Tags
Now that we have all requests being redirected to our HTTPS website, the next step is to ensure that all of our internal links and canonical tags use the HTTPS URLs. This will be either very easy, or very hard, depending on your framework and code structure.
Protocol Relative URLs
You can also use protocol-relative URLs. These are simply URLs that leave off the protocol (the “http” portion). For example, the following is a protocol relative URL:
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Notice that the URL starts with the two double slashes ( // ) because I have not specified the protocol to use. The result of this is that the browser will match the current requests protocol when fetching the resource. This “hack” is widely supported in most major browsers, except:
- IE6 will not know what to do
- IE 7 and IE 8 will download the resource twice, once using HTTP and once using HTTPS
Using a protocol relative (or sometimes called a protocol-less) URL makes it easy to support either HTTP or HTTPS resources based on the requesting page.