Forcing SSL in CodeIgniter

Published by at 23rd June 2018 12:03 pm

I haven't started a new CodeIgniter project since 2014, and don't intend to, but on occasion I've been asked to do maintenance work on legacy CodeIgniter projects. This week I was asked to help out with a situation where a CodeIgniter site was being migrated to HTTPS and there were issues resulting from the migration.

Back in 2012, when working on my first solo project, I'd built a website using CodeIgniter that used HTTPS, but also needed to support an affiliate marketing system that did not support it, so certain pages had to force HTTP, and others had to force HTTPS, so I'd used the hook system to create hooks to enforce this. This kind of requirement is unlikely to reoccur now because HTTPS is becoming more prevalent, but sometimes it may be easier to enforce HTTPS at application level than in the web server configuration or using htaccess. It's relatively straightforward to do that in CodeIgniter.

The first step is to create the hook. Save this as application/hooks/ssl.php:

2function force_ssl()
4 $CI =& get_instance();
5 $CI->config->config['base_url'] = str_replace('http://', 'https://', $CI->config->config['base_url']);
6 if ($_SERVER['SERVER_PORT'] != 443) redirect($CI->uri->uri_string());

Next, we register the hook. Update application/configs/hooks.php as follows:

1<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
3| -------------------------------------------------------------------------
4| Hooks
5| -------------------------------------------------------------------------
6| This file lets you define "hooks" to extend CI without hacking the core
7| files. Please see the user guide for info:
13$hook['post_controller_constructor'][] = array(
14 'function' => 'force_ssl',
15 'filename' => 'ssl.php',
16 'filepath' => 'hooks'
17 );
19/* End of file hooks.php */
20/* Location: ./application/config/hooks.php */

This tells CodeIgniter that it should looks in the application/hooks directory for a file called ssl.php, and return the function force_ssl.

Finally, we enable hooks. Update application/config/config.php:

$config['enable_hooks'] = TRUE;

If you only want to force SSL in production, not development, you may want to amend the ssl.php file to only perform the redirect in non-development environments, perhaps by using an environment variable via DotEnv.