I have a site which has a public and a private area. The private area should be served via HTTPS. I want to redirect once to an explicit HTTPS url, and then, using relative URLS, have all the links be secure. When the user logs out, I will explicitly link to an absolute non-secure HTTP URL.
My login form is shown a non-secure site via regular HTTP. My login form posts to https://www.mysite.com/login/validate
, which loads using a secure connection.
My logs show that Apache is loading the URL via HTTPS and codeigniter is doing its validation correctly.
At the end of my controller function I redirect to /myaccount
using CodeIgniter's URL helper's redirect
method with a relative URL.
redirect('/myaccount');
This causes codeigniter to redirect to a non-HTTPS URL.
My config base_url is non-HTTPS:
$config['base_url'] = "http://www.mysite.com"
This is because some parts of the site are secure while others are not.
Is there a way to tell CodeIgniter to preserve HTTPS when doing relative redirects? Why is it assuming I want to go to a non-HTTPS site if the current controller was loaded via HTTPS and I am doing a relative redirect?
The desired behavior for me is that if I am doing relative redirect, it should preserve the protocol through which the current request was loaded. Instead, it is switching to what the config base_url has defined, even for relative redirects.
Use this:
$config['base_url'] = "http".((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") ? "s" : "")."://".$_SERVER['HTTP_HOST'].str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']);
Instead of this:
$config['base_url'] = "http://www.example.com"
This'll always redirect to where you want it. You don't even have to enter your domain name, just use it as is!
In addition to the above, I also autoload this helper:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
function is_https_on()
{
return isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on';
}
function use_ssl($turn_on = TRUE)
{
$url = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
if ( $turn_on )
{
if ( ! is_https_on() && $_SERVER['HTTP_HOST'] != 'localhost')
{
redirect('https://' . $url, 'location', 301 );
exit;
}
}
else
{
if ( is_https_on() )
{
redirect('http://' . $url, 'location', 301 );
exit;
}
}
}
/* End of file https_helper.php */
/* Location: ./application/helpers/https_helper.php */
With this in place, I can set my individual pages to always use HTTPS/HTTP (either in a single method in my controller, or - if I want it to affect the whole controller - in the constructor).
I simply use:
use_ssl();
at the beginning of the script, to ascertain that it is loaded via HTTPS.
Alternatively, if I only want to serve it through HTTP, I'll use:
use_ssl(FALSE);
There is no 'out of the box' way to handle this HTTPS / HTTP handoff in CI. What you CAN do is create a small helper (that you auto include) which will add a function like secure_url()
, and quite simply returns what a base_url
would, but https format.
You would have to emulate the same redirect
function maybe as secure_redirect()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With