yii - single https-page

Hello I’m looking around how i can easily make a single page in yii https while all others keep http.

Especially the 2nd part of my question is the problematic one… cause when i am on a https-page all links on that page will get https too since yii always uses relative pathes.

What would be the best solution?

Well, look at the CHtml::normalizeUrl() documentation at:

CHtml::normalizeUrl()

You can create custom links by passing non-empty string as the 1st parameter.

Example:


echo CHtml::link('my link', 'https://example.net');

I don’t know how to manipulate http/https, so maybe there is another solution to this.

Hope it helps somehow.

Use createAbsoluteUrl() for the link you want to have with https schema. Like:




echo $this->createAbsoluteUrl('user/login', array(), 'https');



Then create a base controller like this and put it in your components folder:




class BaseController extends CController

{


   public function beforeAction($action)

   {


      if (parent::beforeAction($action))

      {

         

         if (Yii::app()->request->isSecureConnection)

         {


            // Either do this if you want https for an action:

            if ($action !== 'actionName')

            {

               $this->redirect($this->createAbsoluteUrl("{$this->id}/{$action->id}", array(), 'http'), true, 301);

            }


            // Or otherwise this if you want https for a whole controller:

            if ($this->id !== 'controllerName')

            {

               $this->redirect($this->createAbsoluteUrl("{$this->id}/{$action->id}", array(), 'http'), true, 301);

            }


            // Of course you can also check both, controller name and action name if needed


         }


         return true;


      }


   }


}



Then you extend your controller classes from the BaseController like this:




class UserController extends BaseController

{

   ...

}



Now on each request the base controller checks if we’re on a secure https connection. If that’s the case we redirect to the http url if the controller and/or action is not allowed to run under https.

Kind of dirty, but Yii’s url management isn’t very dynamic without modifications. If you want better solution, you may look at CUrlRule and CUrlManager::createUrlRule(). You could add a custom attribute $allowHttps to your custom UrlRule class and redirect from there to the http url. Then in your config you could do:




'urlRules' => array(

   ...

   'user/login' => array('user/login', 'allowHttps' => false),

   ...

),



Though, maybe someone got a better solution in mind.

Well done, Y!!

Your solution is inspiring! :)

Check this out, fairly clean solution. Not sure if it will work with your image issue though.

http://www.jaburo.net/?p=40

Hello,

sorry for the late reply but until now the https-thing wasn’t that important and last time I asked I didn’t understand your code since I was a new Yii user ;)

First a big thanks, your solution was very helpful. I just changed one thing, that I add the $_GET parameters to the absolute URL too and don’t allow redirecting POST requests.

I extended it, so that you can specify an array of all pages, which you like to be https.




public function beforeAction($action)

{

        if (!parent::beforeAction($action))

                return false;


        // only CHANGE http/https status when no POST request

        if ($_POST === array())

        {

                // following code just changes http to https or https to http

                $httpsPages = array(

                        // controller => action(*=all)

                        'user'=>'login',

                );

                $isSSL = false;

                foreach ($httpsPages as $c => $a)

                        if ($this->id==$c && $action->id==$a || $a=='*')

                                $isSSL = true;


                if (Yii::app()->request->isSecureConnection && !$isSSL)

                {

                        $this->redirect($this->createAbsoluteUrl("{$this->id}/{$action->id}", $_GET, 'http'), true, 301);

                }

                elseif (!Yii::app()->request->isSecureConnection && $isSSL)

                {

                        $this->redirect($this->createAbsoluteUrl("{$this->id}/{$action->id}", $_GET, 'https'), true, 301);

                }

        }


        return true;

}



Thumbs up for this solution. Works like a charm.

Hi guys,

I follow the http://www.jaburo.net/?p=40. https only allow at login page not overall page. That is good news but somehow it always say can’t establish a connection to the server at localhost when i click the https://.../login page and other pages still work fine using http. Anyone face this problem before?

Pls help. Thx




Unable to connect


Firefox can't establish a connection to the server at localhost.


  The site could be temporarily unavailable or too busy. Try again in a few

    moments.

  If you are unable to load any pages, check your computer's network

    connection.

  If your computer or network is protected by a firewall or proxy, make sure

    that Firefox is permitted to access the Web.

Can’t establish a connection to the server at localhost when click login page but other pages can run…

protected/components/HttpsFilter.php


class HttpsFilter extends CFilter {

    protected function preFilter( $filterChain ) {

        if ( !Yii::app()->getRequest()->isSecureConnection ) {

            # Redirect to the secure version of the page.

            $url = 'https://' .

                Yii::app()->getRequest()->serverName .

                Yii::app()->getRequest()->requestUri;

                Yii::app()->request->redirect($url);

            return false;

        }

        return true;

    }

}

protected/components/Controller.php


class Controller extends CController

{

    public $breadcrumbs=array();

    public function filterHttps( $filterChain ) {

        $filter = new HttpsFilter;

        $filter->filter( $filterChain );

    }

}

controllers/SiteController


public function filters()

{

    return array(

        'https +login', // Force https, but only on login page

    );

}

Hi,

Can anyone help me or give me a sign??

Thanks man.