Netshine Software Limited






Home arrow Joomla and SSL Make Text BiggerMake Text SmallerReset Text Size
Using an SSL Certificate with your Joomla Website

Please note, this page refers to modifying Joomla 1.0.x to use an SSL certificate and switch between http and https automatically. It does not apply at all to the Joomla 1.5 series, only 1.0, and has been tested on versions up to and including 1.0.15.

The simplest way of using Joomla with an SSL certificate is to run your entire site over https. To do this, you will need to add redirects from your http pages to the https versions (typically using a mod_rewrite rule), and make sure that the $mosConfig_live_site value in your configuration.php file contains your https URL.

However, that is not a very satisfactory solution not least because running your site over https is noticeably slower than http.  Typically, you will want the Joomla administrator to run over https, and the front-end website to run over http - perhaps switching to https when a user logs in.  Joomla 1.0.x versions do not support this behaviour natively - to get it working, it is necessary to make some small hacks to certain Joomla files... (ed: Joomla 1.0.12 now ostensibly supports https, although it will not switch automatically between http and https on login, and in our experience, it tends to revert the 'live site' setting back to http before it gets to the template, thus not serving everything over https).

Always make sure you are running the latest stable version of Joomla.  Back everything up before you start!

Disclaimer: The following hacks work for me, but are not guaranteed to work on every server configuration or Joomla installation. Use of these hacks is entirely at your own risk! 

To make sure the Joomla administrator always runs over https...

In administrator/index.php, immediately after the line that says

define( '_VALID_MOS', 1);

Add the following:

//Redirect to https if accessed over http (except when running locally) if ($_SERVER['SERVER_NAME'] != "localhost")
{
  $port = $_SERVER["SERVER_PORT"];
  $ssl_port = "443";  //Change 443 to whatever port you use for https (443 is the default and will work in most cases) 
  if ($port != $ssl_port)  
  {
    $host = $_SERVER["HTTP_HOST"];
    $uri = $_SERVER["REQUEST_URI"];
    header("Location: https://$host$uri");
  }
}

Also add the above code to /administrator/index2.php - immediately after the require_once directives near the start. 

This forces the administrator to always use https. However, if you are using IE and find that it keeps warning you about insecure items on the page, you will have to add the code from part 1 to the end of your configuration.php file instead.  Note however, that the code you add there will be lost whenever you save the 'Global Configuration' page in Joomla (so you will either have to re-add it after saving, or preferably make changes directly in configuration.php instead of using the Joomla 'Global Configuration' screen).

To enable the front-end to support https...

Note: The following hacks are not necessary as of version 1.0.14: 

Since 1.0.12, we have found it necessary to add the following to the start of the template's index.php file (not the main Joomla index.php):

<?php
global $mosConfig_live_site;
if ($_SERVER['SERVER_PORT'] == 443)
{
  $mosConfig_live_site = str_replace("http://", "https://", $mosConfig_live_site);
}
?> 

In order to avoid problems with session cookies while switching from http to https, you will need to edit a line in the includes/joomla.php file.  Find the line (round about line 904) that says:

return md5( 'site' . $mainframe->getCfg( 'live_site' ) ); 

...and replace it with the following:

if (strpos($mainframe->getCfg('live_site'), 'http://localhost') !== false) {return md5( 'site' . $mainframe->getCfg( 'live_site' ) );} else {return md5( 'site' . str_replace("http://", "", str_replace("https://", "", $mainframe->getCfg( 'live_site' ))) );}

These hacks enable Joomla to be able to handle both http and https.  They do not however cause your site to automatically switch to https.  There are 2 ways to acheive this:

1) Instead of using the login module, use the login component, and link to it from a menu item of type URL - specifying https in the URL.  For example, you could create a menu item that points to https://www.yourdomain.com/index.php?option=com_login&Itemid=1 - that way the entire login process is handled using https.

2) If you want to keep the login module, the login form itself will not be shown over https, however by making the following alterations, the login submission is still protected as the form will be submitted over https when the user clicks on login. In other words, it is just as secure as using option 1, but the user will not see a padlock icon until after they have logged in. Note: You can now redirect the user to an https URL after login by setting the parameter in the module (without any hacks), however, that will not protect the actual login form itself, as that will still be submitted over http, so the following hack is still necessary for proper security.

For both options, you need to make a small amendment to the login form.  If you are using option 1, the form to be altered is in the components/com_login/login.html.php file.  If using option 2, it is in modules/mod_login.php.  There is nothing stopping you using both methods, in which case you will need to alter both files.

In modules/mod_login.php, look for the line that says:

<form action="<?php echo sefRelToAbs( 'index.php' ); ?>" method="post" name="login" >

Make sure you get the login one, not the logout one (ie. make sure it 'index.php', not 'index.php?option=logout' in the middle bit).  Replace that line with the following:

<form action="<?php echo strpos($mosConfig_live_site, 'http://localhost') !== false ? sefRelToAbs( 'index.php' ) : sefRelToAbs( str_replace('http://', 'https://', $mosConfig_live_site) . '/index.php' ); ?>" method="post" name="login" >

It is also now necessary to find the following code (still in mod_login.php):

<input type="hidden" name="return" value="<?php echo htmlspecialchars( sefRelToAbs( $login ) ); ?>" />

...and replace it with:

<input type="hidden" name="return" value="<?php echo str_replace('http://', 'https://', htmlspecialchars( sefRelToAbs( $login ) )); ?>" />

You can also optionally redirect to http when the user logs out by changing the logout form as well.  Look for the line (nearer the start of modules/mod_login.php) that says:

<form action="<?php echo sefRelToAbs( 'index.php?option=logout' ); ?>" method="post" name="logout">

Make sure you get the one that says 'index.php?option=logout' in the middle.  Replace it with:

<form action="<?php echo sefRelToAbs( str_replace('https://', 'http://', $mosConfig_live_site) . '/index.php?option=logout' ); ?>" method="post" name="logout">

You also need to search for:

<input type="hidden" name="return" value="<?php echo htmlspecialchars( sefRelToAbs( $logout ) ); ?>" />

...and replace it with:

<input type="hidden" name="return" value="<?php echo str_replace('https://', 'http://', htmlspecialchars( sefRelToAbs( $logout ) )); ?>" />

If you are using the login component, and have specified an https URL to link to the login page, there is no need to hack the component in order to ensure the user stays in https when they login (because the https URL link will switch you into https already). But if you want to make sure that even if someone accesses the page over http, they still submit their login details over https, you would still need to apply this hack:

To update the login component, go to components/com_login/login.html.php, find the line (quite near the start) that says:

<form action="<?php echo sefRelToAbs( 'index.php?option=login' ); ?>" method="post" name="login" id="login">

Replace it with:

<form action="<?php global $mosConfig_live_site; echo strpos($mosConfig_live_site, 'http://localhost') !== false ? sefRelToAbs( 'index.php?option=login' ) : sefRelToAbs( str_replace('http://', 'https://', $mosConfig_live_site) . '/index.php?option=login' ); ?>" method="post" name="login" id="login">

It is also necessary to find the bit that says:

<input type="hidden" name="return" value="<?php echo sefRelToAbs( $return ); ?>" />

...and replace it with:

<input type="hidden" name="return" value="<?php echo str_replace('http://', 'https://', sefRelToAbs( $return )); ?>" />

If you want to revert back to http when they log out (regardless of whether or not you applied the above hack), scroll down to the logoutpage function (near the end of the file), and find the line that says:

<form action="<?php echo sefRelToAbs( 'index.php?option=logout' ); ?>" method="post" name="login" id="login">

Replace it with:

<form action="<?php global $mosConfig_live_site; echo sefRelToAbs( str_replace('https://', 'http://', $mosConfig_live_site) . '/index.php?option=logout' ); ?>" method="post" name="login" id="login">

You also need to find:

<input type="hidden" name="return" value="<?php echo sefRelToAbs( $return ); ?>" />

...and replace that with:

<input type="hidden" name="return" value="<?php echo str_replace('https://', 'http://', sefRelToAbs( $return )); ?>" />

Session Handling for Users Behind Proxies

Joomla 1.0.x stores session information using a cookie whose value is derived from the user's IP address. If the user is behind a proxy, this does not work properly without an additional hack as follows:

In the /includes/joomla.php file, add the following code to the end of the file, just before the closing PHP tag: ?>

function ssl_hack_user_IP()
{
  $ip = "";

  if (isset($_SERVER))
  {
      if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]))
      {
          $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
          if (strpos($ip, ",") !== false)
          {
              $ip_array = explode(",", $ip);
              $ip = $ip_array[0];
          }
      }
      elseif (isset($_SERVER["HTTP_CLIENT_IP"]))
      {
          $ip = $_SERVER["HTTP_CLIENT_IP"];
      }
      else
      {
          $ip = $_SERVER["REMOTE_ADDR"];
      }
  }
  else
  {
      if ( getenv( 'HTTP_X_FORWARDED_FOR' ) )
      {
          $ip = getenv( 'HTTP_X_FORWARDED_FOR' );
          if (strpos($ip, ",") !== false)
          {
              $ip_array = explode(",", $ip);
              $ip = $ip_array[0];
          }
      }
      elseif ( getenv( 'HTTP_CLIENT_IP' ) )
      {
          $ip = getenv( 'HTTP_CLIENT_IP' );
      }
      else
      {
          $ip = getenv( 'REMOTE_ADDR' );
      }
  }
  return $ip;
}

Then, around line 927 in the same file, you will find a function called sessionCookieValue - in Joomla 1.0.15, it runs from line 927 to line 953. Within that function, replace all 3 occurrences of:

$_SERVER['REMOTE_ADDR'] 

...with this:

ssl_hack_user_IP()

There are 3 places where you need to make that replacement: lines 938, 943, and 950. Thanks to Tony Meyer for pointing out the need for this session handling hack.

 
SSL Certificates
We are now able to offer a low cost SSL certificate for your domain, from just £35 per year.

Joomla! Tutorial
Take a look at our free tutorial for Joomla! Administrator...


 
 
© 2004-2009 Netshine Software Limited   Terms and Conditions   Search Engine Optimisation by Blogstorm