Welcome Guest, Not a member yet? Register   Sign In
How I did SSL
#1

[eluser]aggrav8d[/eluser]
Hello, my fellow pyros.

I tried to look for a good SSL solution on here. Maybe I didn't look hard enough.
I found one that recommended rewriting every url on a page from "http" to "https".
If only part of your site is SSL then that solution is a problem when IE users
leave the "safe zone" and start seeing messages about insecure content.

In any case, I'd like to fill the knowledge gap. I hope you find my method elegant.

We have several possible cases to consider:

- a regular page that links to a secure page
- a secure page that links to a regular page
- a secure page that loads secure content from a shared header file
- a regular page that loads content from a shared header file

In each case URLs could change in two ways: A different URL transport and (potentially) a different base URL. I added a

Code:
$config['base_url']     = 'http://www.myurl.com/';
// new hotness
$config['base_url_ssl'] = 'https://secure.myurl.com/';

to config.php. I then made big changes in urlhelper.php
Code:
...
    function site_url($uri = '',$ssl=FALSE)
    {
        $CI =& get_instance();
        return $CI->config->site_url($uri,$ssl);
    }
...
    function base_url($ssl=FALSE)
    {
        $CI =& get_instance();
        return $CI->config->slash_item($ssl?'base_url_ssl':'base_url');
    }
...
    function current_url($ssl=FALSE)
    {
        $CI =& get_instance();
        return $CI->config->site_url($CI->uri->uri_string(),$ssl);
    }
...
    function anchor($uri = '', $title = '', $attributes = '',$ssl=FALSE)
    {
        //$title = (string) $title;
        //echo $ssl?'<h1>test</h1>':'';

        if ( ! is_array($uri))
        {
            $site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri,$ssl) : $uri;
        }
        else
        {
            $site_url = site_url($uri,$ssl);
        }

        if ($title == '')
        {
            $title = $site_url;
        }

        if ($attributes != '')
        {
            $attributes = _parse_attributes($attributes);
        }

        return '<a href="'.$site_url.'">'.$title.'</a>';
    }
...
    function anchor_popup($uri = '', $title = '', $attributes = FALSE,$ssl=FALSE)
    {
        $title = (string) $title;

        $site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri,$ssl) : $uri;

        if ($title == '')
        {
            $title = $site_url;
        }

        if ($attributes === FALSE)
        {
            return "<a href='[removed]void(0);'>".$title."</a>";
        }

        if ( ! is_array($attributes))
        {
            $attributes = array();
        }

        foreach (array('width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0', ) as $key => $val)
        {
            $atts[$key] = ( ! isset($attributes[$key])) ? $val : $attributes[$key];
            unset($attributes[$key]);
        }

        if ($attributes != '')
        {
            $attributes = _parse_attributes($attributes);
        }

        return "<a href='[removed]void(0);'>".$title."</a>";
    }
...
    function redirect($uri = '', $method = 'location', $http_response_code = 302,$ssl=FALSE)
    {
        if ( ! preg_match('#^https?://#i', $uri))
        {
            $uri = site_url($uri,$ssl);
        }
        
        switch($method)
        {
            case 'refresh'    : header("Refresh:0;url=".$uri);
                break;
            default            : header("Location: ".$uri, TRUE, $http_response_code);
                break;
        }
        exit;
    }
I also needed to make a small change to /libraries/Config.php
Code:
function site_url($uri = '',$ssl=FALSE)
    {
        if (is_array($uri))
        {
            $uri = implode('/', $uri);
        }
    
    $base=($ssl===TRUE)? 'base_url_ssl' : 'base_url';
    
        if ($uri == '') {
            return $this->slash_item($base).$this->item('index_page');
        } else {
            $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
            return $this->slash_item($base).$this->slash_item('index_page').trim($uri, '/').$suffix;
        }
    }
...
    function system_url($ssl=FALSE)
    {
        $x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH));
        return $this->slash_item(($ssl? 'base_url_ssl' : 'base_url')).end($x).'/';
    }
As long as you have been consistent and used anchor/site_url/base_url throughout your code, making the above changes should be as easy as cut & paste.

Let me know if that helps.

Thanks! Keep up the great (frame)work!

Edited to add in a couple missing lines.
#2

[eluser]aggrav8d[/eluser]
Right. I thought about it today and realized this post was only half finished. I dumped a lot of code in your laps and didn't explain why I did what I did.

As I said, we have several possible cases to consider:

- a regular page that links to a secure page
- a secure page that links to a regular page
- a secure page that loads secure content from a shared header file
- a regular page that loads content from a shared header file

A typical example would be a header file that contains a menu. In my case - www.abbeycustomblinds.ca - the menu had links to the homepage, some important categories, and the cart. The cart page also included all the form information necessary to checkout. (One step checkout is about as easy as it gets.) Naturally, it had to be SSL because of the credit cards.

In each controller I would have a variable
Code:
...
  function index() {
    // ...
    $data['secure_page']=1;  // 0 or undefined for non-SSL pages
    $this->load->view('cart',$data);
  }
...
views/cart.php would include views/header.php which would
Code:
&lt;?php
$secure=(isset($secure) && $secure==1);
//...
anchor('/home','Home');  // never https
//...
anchor('/cart','My Cart',TRUE);  // always https
//...
// espresso on a secure page, decaf on a regular page.
echo "<img src='".site_url("/tmp/images/whatever",$secure)."' alt='' />";
This way I don't have to rewrite anything. I'm tempted to create an admin control panel that would let administrators dynamically adjust which pages are secure and which are not.

I hope that makes things a little more useful.

g'night!
#3

[eluser]aggrav8d[/eluser]
To whom it may concern, I had to rewrite the last line of code in the second article three times because there was some kind of auto-edit removing everything inside the (). It wouldn't stop until I switched to double quotes. I hope that didn't break any of the other code I posted.
#4

[eluser]acormack[/eluser]
Hi aggrav8d,

This is a great contribution you have made. Like you I didn't fancy hacking my apache config to do this!

I think you may have a typo in the follow-up post though. I believe it should read

Code:
$secure=(isset($secure_page) && $secure_page==1);

Many thanks for posting this. It should be proposed for inclusion in the next release of CI.

Regards


Alec
#5

[eluser]ontguy[/eluser]
Thanks for the contribution.

I'm wondering if you considered the approach suggested here: http://ellislab.com/forums/viewthread/135039/
#6

[eluser]Sbioko[/eluser]
Thanks! I think, that it will be useful!
#7

[eluser]acormack[/eluser]
aggrav8d

As you say above it appears that the bulletin board software does not display the text string that has been pasted in - even inside code tags.


You need to change the return value of the anchor function to include the $attributes variable after the $site_url:

Code:
return '<a href="'.$site_url.'">'.$title.'</a>';

Note: Whatever I try I cannot get the $attributes variable to display if I paste it in above.

Many Thanks for providing this code.

Alec
#8

[eluser]aggrav8d[/eluser]
[quote author="ontguy" date="1270684074"]Thanks for the contribution.

I'm wondering if you considered the approach suggested here: http://ellislab.com/forums/viewthread/135039/[/quote]

Yes, and threw it out. Imagine you go to a page that has force_ssl. it converts all http:// to https://, including the ones that are supposed to a href back to non-secure pages. When I surf back to those pages they are not calling force_ssl(). Net effect? the page is loaded https and all of it's linked data (images, javascript, css) are NOT loaded via https. Most browsers (especially IE) throw a nasty warning and frighten users.
#9

[eluser]natanv[/eluser]
Thanks bro! You saved me some much appreciated time.

I ended up going with a hybrid approach by using your config + url_helper in conjunction with Jamie's "force_ssl" helper which I modded by removing:

$CI->config->config['base_url'] = str_replace('http://', 'https://', $CI->config->config['base_url']);

since I was using your functions to secure the needed links.
#10

[eluser]InsiteFX[/eluser]
I hope you extended the config library and did not hack it.

Also url_helper should be MY_url_helper

InsiteFX




Theme © iAndrew 2016 - Forum software by © MyBB