Module Reference for Secure Pages: https://drupal.org/project/securepages

Introduction

Secure Pages is a module designed to create a "mixed-mode" session between HTTP and HTTPS requested pages. By the nature of SSL (https) there are more requests and responses between a secure connection, usually making HTTPS pages slightly slower than their non-secure HTTP counterparts. Improvements have been made to make the SSL protocol faster, but many of the various methods haven't been widely adopted. If you do a web search for "optimize ssl", you will find a wealth of articles and blog posts on how you can tune SSL to push a bit more speed. But we aren't here to dive into the full details about SSL, if you're curious about Secure Pages, chances are you already know the history of securing a website and you want to secure yours.

Pre-Installation

Before you can ever use Secure Pages, your site must have an SSL certificate installed and working. One way you "should" be able to test if your site is setup properly, is to visit your website using https:// instead of http://. If the site opens normally with the https:// protocol, you should be golden to continue with the installation and config of Secure Pages. On a side note, Secure Pages will check to see if SSL is working properly. If it isn't, you won't be able to configure anything until it's fixed.

Installation

*Note: As of this writing, Secure Pages is on a "stable release freeze" until several core issues are resolved. This will require two patches to be installed ontop of core to make Secure Pages work properly. Any updates to core will require the re-patch.

Also, This document was crafted for Drupal 7, however the majority of its information is applicable to Drupal 6.

Install Secure Pages:

  1. Download the module from: https://drupal.org/project/securepages - If you want to use the semi-stable beta version, it works pretty well but several issues have been fixed in the latest dev version.

    For Drush use:

    drush dl securepages
    
  2. Extract the module to your /sites/all/modules folder
  3. Enable the Secure Pages module

Install Finalization Tweaks

Now that Secure Pages is installed and enabled, we need to make a few changes to bring it all together: Force www or non-www redirect and add a configuration line to settings.php.

Force redirect www or non-www
If you don't already have your site setup to force one or the other redirects from www to non, or non-www to www, it's really easy to do. First off, you need to decide if you want http://www.yourdomain.com or http://yourdomain.com

  1. Open the .htaccess file located in the root of your Drupal directory. As of Drupal 7.22, the line of the file we need to go to is 81 which is where it says:
      # If your site can be accessed both with and without the 'www.' prefix, you
      # can use one of the following settings to redirect users to your preferred
      # URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
      #
      # To redirect all users to access the site WITH the 'www.' prefix,
      # (http://example.com/... will be redirected to http://www.example.com/...)
      # uncomment the following:
      # RewriteCond %{HTTP_HOST} .
      # RewriteCond %{HTTP_HOST} !^www\. [NC]
      # RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
      #
      # To redirect all users to access the site WITHOUT the 'www.' prefix,
      # (http://www.example.com/... will be redirected to http://example.com/...)
      # uncomment the following:
      # RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
      # RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]
    

    If you want the WWW, then remove the hash # from the following lines:

       RewriteCond %{HTTP_HOST} .
       RewriteCond %{HTTP_HOST} !^www\. [NC]
       RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    

    If you DON'T want the WWW, then remove the hash # from the following lines:

       RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
       RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301]
    

    Rewrite Base - Optional
    This step might or might not be necessary to make things work. By default, the RewriteBase / is commented out. If you're having problems getting Secure Pages to work, you might try uncommenting this line.

    Save and exit the .htaccess file because that part is done!

    settings.php Configuration

    There are several things we need to do within the settings.php file. First let's open it up. You can find it located in: /sites/default/settings.php

    Adding the $conf line
    First, we need to add the configuration line $conf['https'] = TRUE; to this file to basically tell Drupal what to do with HTTPS requests. You can put it anywhere in the file, but for simplicity, I put it up at the very top so it will look like this:

    <?php
    
    $conf['https'] = TRUE;
    
    // $conf['image_allow_insecure_derivatives'] = TRUE;
    
    /**
     * @file
     * Drupal site-specific configuration file.
     *
    .......
    

    Setting the Base URL

    Note: This option may or may not be necessary. Some have reported that they need it, others have reported it breaks caching of their site. For an all inclusive workaround, check out: https://www.drupal.org/node/1406686

    In order to set set the $base_url, look around line 267 for:

    # $base_url = 'http://www.example.com';  // NO trailing slash!
    

    Remove the # to uncomment it and change the http://www.example.com to your domain name. If you aren't forcing www, then don't add it and pay close attention to the domain being enclosed in the apostrophes (' ')

    Another thing to note, if you're primarily forcing https, then you might want to set your base_url to reflect https instead. Otherwise, leave it as http.

    Adding the Cookie Domain

    Note: Some have made comments that this is not necessary, or causes issues with their site. It's a recommended setting, but not explicitly required.

    To set the cookie domain, find the line around 324 that says:

    # $cookie_domain = '.example.com';
    

    Remove the # to uncomment it and change the .example.com to whatever your domain is. Don't add the www and make sure to leave the leading period (.example)

    Save and exit the settings.php file, we're all done with it.

    ---

    At this point, the module installation is done!

    //Start Core Patch - Remove from documentation once 1.0 stable is released

    Installing the core Patches

    Since core Drupal has a few bugs of it's own, it's preventing the stable release of Secure Pages. These bugs are already known about and must be first fixed in Drupal 8, before they are backported to Drupal 7. Meaning, it might be awhile before Secure Pages goes full on stable. No worries though, that's what the patches are for! Unfortunately, patches can be a little daunting. The absolute easiest way (which is outlined below) is to install it using command line tools by having shell access to your website. If you don't know what that is or don't have access to it, you might have to change the file by hand which can be a bit tricky if you aren't careful.

    Patch #1: #961508-21: Dual http/https session cookies interfere with drupal_valid_token()

    If you clicked the link above, you probably noticed that the test status is FAILED: and that's OK. It failed because it didn't pass the tests for Drupal 8 because it's designed to work with Drupal 7.

    1. Download the patch to the root of your Drupal directory: https://drupal.org/files/961508-20.patch
    2. Through your shell command line tool, enter the following to apply the patch
      patch -p1 < 961508-20.patch
      
    3. If everything worked, you should see some output like "hunk succeeded" or something like that and you're good to go.

    Patch #2: #471970-13: DrupalWebTestCase->getAbsoluteUrl should use internal browser's base URL

    Again, this patch shows that it FAILED testing, but it works just fine on Drupal 7.

    1. Download the patch to the root of your Drupal directory: https://drupal.org/files/issues/471970_0.patch
    2. Through your shell command line tool, enter the following to apply the patch
      patch -p1 < 471970_0.patch
      

    If everything worked, you should see some output like "hunk succeeded" or something like that and you're good to go.

    That's it for the Patches! We can move on to setting up Secure Pages to work with your website.

    //End Core Patch

    Accessing Secure Pages Settings

    Accessing the settings by menu
    Navigate to: Configuration -> System -> Secure Pages

    Accessing the settings by URL
    Browse to: http://(yoursite)/admin/config/system/securepages

    Using Secure Pages

    Enable / Disable

    The first option with Secure pages is to either Enable or Disable it. It's disabled by default and the ability to enable it will either be a normal radio button, or it will be grayed out and you can't change it. If the SSL certificate isn't setup on your website or it isn't working, you won't be able to enable this setting.

    Mixed Mode Setting

    Remember back in the introduction, it was mentioned that you can have a "Mixed Mode" website? That means that some pages will be served as http, others will be served as https.

    The next setting is where you enable the mixed mode setting and it is labeled as: Switch back to http pages when there are no matches. Simply put a check in the box if you want mixed mode and move on.

    Setting The Domains

    This part is pretty self explanatory, but I'll give you some examples of what to put. I'm going to use the WWW in the examples, (remember we forced the WWW or non-WWW earlier?) so make sure you use whatever you forced your website to use.

    Non-secure Base URL

    http://www.yourdomain.com
    

    Secure Base URL

    https://www.yourdomain.com
    

    Including or Excluding Secure Pages

    In the section Pages which will be be secure we will either "include" or "exclude" pages that will be secure.

    Make secure every page except the listed pages.
    If you want the majority of the site to be served secure as HTTPS, then choose this setting.

    Make secure only the listed pages.
    If you want the majority of the website to be served as HTTP, then you will want to use this setting.

    ---

    Both choices require that you use a URL that you want to include or exclude. As the documentation from the settings page states, you can use the alias of a page with a * as a wildcard. For example, assuming I only want certain pages to be secure, here's a list of pages that I would add to the list:

    node/add
    node/add/*
    node/*/edit
    node/*/edit/*
    node/*/delete
    user
    user/*
    users
    users/*
    admin
    admin/*
    

    I will note that you can use the wild card to include a base URL along with any sub-URL's, for example: user* will do both /user and /user/bob. Let me note that it "works", but there isn't any concrete documentation (that I have found) that says this is an "OK" thing to do with Drupal. It's just something I found does infact work, but most developers will stress the user and user/* method.

    Ignoring URL's

    If you want Secure Pages to always ignore a URL, set it in the Ignore pages section. This completely skips the URL from being transformed one way or the other and it will always be rendered as the default method. This is mainly for things like ajax, captchas, file cache's etc that always seem to break pages. These URL's are usually setup as */urlpath/* which means that match can be anywhere within the URL structure.

    Forcing It On A Role

    If you ALWAYS want a particular user role to be forced (assumed) with https, then you can check off the user role in the User roles section. Keep in mind that if you have a lot of logged in users accessing pages that are not content sensitive like adding content, or filling out forms, then you'll have a slight speed penalty for always forcing the secure connection. Leaving this disabled and just adding the specific admin or content pages that need to be secure is usually the preferred route.

    Problems? Enable Debugging

    Having problems with Secure Pages and can't quite track down the source? Enable Debugging is a new feature as of June 2013 that will output some information in the message status area of every https requested page.

    Tips, Tricks and Workarounds

    (This should be an on-going area of development)

    Playing Nice With Boost

    For the last century, Boost and Secure Pages have fought like children. Ok, not really, but they have their issues when used together. If you're running a mixed mode environment with HTTP being the default, there are a few things you can do to make them play... nicer... together. Even as recent as June 2013, there have been some improvements to getting the two to work better together.

    1. Make sure boost has the Bypass the boost cache for ssl requests. enabled on the .htaccess tab. If this was previously disabled, you will need to re-add the .htaccess generation information into your .htaccess file.
    2. Manually ignore Boost caching for all anonymous requested https pages. In your Boost Settings tab, you have the Cache specific pages section where you can explicitly tell Boost not to cache pages that will be HTTPS. For example, you might have your /contact page secure, so tell boost not to cache your /contact page. Failure to do this workaround will result in a cached https page that get's redirected back to http and stays that way. Forever. (Well, until the cache expires)

    Playing Nice With Shopping Carts

    There are several areas of documentation that outline some issues with Commerce and Ubercart.

    Ubercart
    How to use HTTPS to protect customer data

    Commerce
    Problems with checkout when using SSL
    Does Drupal Commerce require secure connections?
    Frustrated! SSL checkout & cart not working

    Additional Resources

Comments

sonicthoughts’s picture

This is some of the best documentation I've ever seen - thanks! about 80% of the issues would be cleared up if people read this. One question, why is it necessary to set $cookie_domain and $base_url. I've seen several comments that the former is not necessary and the latter should be blank, uncommented or something like this: #1406686: HTTPS/HTTP, drupal page caching, and base_url break caching. Please try to get this prominently on the module page !

siva.thanush’s picture

Hi,
Nice tutorials.
I have a different probelm,

I am haivng a Multisite drupal installtion.
The server is certified.
I can see all the sites on the server having https://site1.com,https://site2.com,https://site3.com,https://site4.com.

But in none of the site the subpages are having the "https://", I want to enable the same for my /user page atleast but i could'nt do that.
Can you help me to do that for my subpages or the /user page atleast.

PS:

The secure pages module is not allowing me to change the Enable/Disable option.

Thank you,
Regards,

Siva

Siva

sdmeyers’s picture

One issue we are having is that if we want to force https for a page (i.e. WebApps) we can use this webapps in the Pages list and www.site.com/webapps works as expected (redirects to https) however, www.site.com/WebAppsdoes not. For some reason even adding WebApps to the pages lists still doesn't work.

Any suggesting why, or how to work around this?

joshuautley’s picture

Recently I've had the need to force HTTPS for some eCommerce sites. After an exhaustive search for a Drupal related answer I just had to test the multitude of solutions I found.

This is what I found to work for two sites running Ubercart SSL (not secure pages). It may be of use for those using Secure Pages as well.

# .htaccess cond/rule does not work - It creates an incorrect redirect
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

/* PHP code does work! - place it at the top of settings.php */
if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
if(!headers_sent()) {
header("Status: 301 Moved Permanently");
header(sprintf(
'Location: https://%s%s',
$_SERVER['HTTP_HOST'],
$_SERVER['REQUEST_URI']
));
exit();
}
}

Josh Utley, President & CEO
Intrepid Network Inc. | Multimedia Services & Business Solutions

"Our mission is to provide a more personable multimedia service along with the highest quality business solutions."

quantos’s picture

Thanks Josh. Testing and following.

Don't shoot me. I'm just a designer.

a_holownia@hotmail.com’s picture

Thanks you for this, I've been working on forcing https throughout my site whilst also redirecting anybody who goes to the http:// version to the https:// version and this did the trick. Much appreciated!

katin’s picture

Just FYI, with that code in settings.php, drush arb breaks (will error out without being able to backup).

(Drush version 6.5, maybe other versions, too.)

bdimaggio’s picture

I found that setting $base_url, per these instructions, led to "this webpage has a redirect loop" errors (at least in Chrome; I didn't test other browsers). After reading #2049421: This webpage has a redirect loop, I commented $base_url out again and that issue cleared up.