Quantcast

Re: Login through HTTPS on CakePHP

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Login through HTTPS on CakePHP

Mariano Iglesias

This is an auto-response so other people can find a possible method to
solve this.

The idea was to allow certain actions (such as any action within the
Account controller) to *only* be accessed through SSL.

First of all, I wanted to have an array of all actions that should only
be accessed through HTTPS. So in boostrap.php I added:

$GLOBALS['AppConfig'] = array(
        'SSLActions' => array (
                'account/*'
        )
);

This means that any action within the account controler must be
accessed through SSL.

Then, I had to extend the Html helper. Now, I didn't want to make a
copy of this helper and then modify, but I wanted to inherit from it
and create my own html helper, so in the future new things could be
added and if ever the html helper gets improved i wouldn't be loosing
those improvements. So I created a new helper called SyHtml, with this
code:

require_once(CAKE_CORE_INCLUDE_PATH . DS . 'cake' . DS . 'libs' . DS .
'view' . DS . 'helpers' . DS . 'html.php');

class SyhtmlHelper extends HtmlHelper
{
        function url($url = null, $return = false)
        {
                if (isset($GLOBALS['AppConfig']) &&
isset($GLOBALS['AppConfig']['SSLActions']) && isset($url) && trim($url)
!= '')
                {
                        $current_url = ($url{0} == '/' ? substr($url, 1): $url);

                        $current_url_is_ssl = false;

                        foreach($GLOBALS['AppConfig']['SSLActions'] as $current_ssl_action)
                        {
                                if (strpos($current_ssl_action, '*') !== false)
                                {
                                        $current_pattern = $current_ssl_action;
                                        $current_pattern = str_replace('/', '\\/', $current_pattern);
                                        $current_pattern = str_replace('*', '(.*)', $current_pattern);

                                        $current_url_is_ssl = preg_match('/' . $current_pattern . '/i',
$current_url);
                                }
                                else if (strcasecmp($current_ssl_action, $current_url) == 0)
                                {
                                        $current_url_is_ssl = true;
                                }

                                if ($current_url_is_ssl)
                                {
                                        break;
                                }
                        }

                        if (($current_url_is_ssl && !$this->_in_ssl()) ||
(!$current_url_is_ssl && $this->_in_ssl()))
                        {
                                $url = parent::url($url, true);

                                $url = ($url{0} == '/' ? substr($url, 1): $url);

                                $current_base_url = ($current_url_is_ssl ? 'https://' : 'http://');
                                $current_base_url .= $_SERVER['SERVER_NAME'];
                                $current_base_url .= (!$this->_in_ssl() && $_SERVER['SERVER_PORT']
!= 80 ? ':' . $_SERVER['SERVER_PORT']: '');

                                $url = $current_base_url . '/' . $url;

                                return $this->output($url, $return);
                        }
                }

                return parent::url($url, $return);
        }

        function _in_ssl()
        {
                return (isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'],
'on') == 0 ? true : false);
        }
}

Since I'm extending the url() method, any other html helper function
that uses this method will be using our version (as long as we used the
SyHtml helper). For example, on layout.thtml I have the following:

<?php echo $syhtml->link('Login', '/account/login', array('class' =>
'login')); ?>
<?php echo $syhtml->link('Forgot', '/account/forgot'); ?>

Our helper will see that these two links should be linked to their
HTTPS version.

Finally, on the AppController class I add the following code to the
beforeRender() method:

if (isset($GLOBALS['AppConfig']) &&
isset($GLOBALS['AppConfig']['SSLActions']))
{
        $current_url = ($this->here{0} == '/' ? substr($this->here, 1):
$this->here);

        $current_url_is_ssl = false;

        foreach($GLOBALS['AppConfig']['SSLActions'] as $current_ssl_action)
        {
                if (strpos($current_ssl_action, '*') !== false)
                {
                        $current_pattern = $current_ssl_action;
                        $current_pattern = str_replace('/', '\\/', $current_pattern);
                        $current_pattern = str_replace('*', '(.*)', $current_pattern);

                        $current_url_is_ssl = preg_match('/' . $current_pattern . '/i',
$current_url);
                }
                else if (strcasecmp($current_ssl_action, $current_url) == 0)
                {
                        $current_url_is_ssl = true;
                }

                if ($current_url_is_ssl)
                {
                        break;
                }
        }

        if ($current_url_is_ssl && (!isset($_SERVER['HTTPS']) ||
strcasecmp($_SERVER['HTTPS'], 'on') != 0))
        {
                // Should be accessed only via SSL

                $current_url = 'https://' . $_SERVER['SERVER_NAME'] . '/' .
$current_url;

                return $this->redirect($current_url);
        }
}

This prevents people from trying to access directly to the action via
normal HTTP.

All of this is supposed to work when you have your cake HTTPDOCS and
HTTPSDOCS on the same directory.

Hope it helps :)

-MI


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Cake PHP" group.
To post to this group, send email to [hidden email]
To unsubscribe from this group, send email to [hidden email]
For more options, visit this group at http://groups.google.com/group/cake-php
-~----------~----~----~----~------~----~------~--~---

Loading...