Forcing Https in Yii

Hi! I’m using the filter class http://www.jaburo.net/?p=40 made by Edgar Ngwenya, which I think works pretty cool.


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;

    }

}

The problem is that once the filter is called, the secure connection stays activated, when what I want is have https just in certain pages (actions) of my site.

So what I have done is copy the filter to make a HttpFilter.php


class HttpFilter extends CFilter 

{

    protected function preFilter($filterChain) 

    {

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

        {

            $url = 'http://' .

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

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

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

            return false;

        }

        return true;

    }

}

And I add the filter in the controller for the actions where I don’t want https:




public function filters()

    {

        return array(

            'https +new, payment',

            'http +index, complete'

        );

    }

This works, but I’m not sure if it’s a good approach. What do you think?

Thanks, Pablo.

This is a good question. I would also like to know the answer. Please post back if you have resolved it. Thanks!

The principle of this method sounds perfectly fine, but filtering http(s) at this point is pretty late, because Yii has already started up and everything. It would be better to catch an redirect the request earlier.

I would do this in the .htaccess file.

Also make sure that your application creates the correct URLs for the different part so you avoid redirects as much as possible.

So instead of making a link for http and relying on .htaccess to rewrite to https make the link to https directly. This will save one rewrite and thus be faster.

A good example for the .htaccess can be found here http://www.sitepoint.com/forums/showthread.php?534242-Force-HTTPS-HTTP-with-.htaccess

Now that I have had a little bit of time to go back to this topic, I have understood what I was doing wrong.

So I’m keeping the HttpsFilter of Jarubo, but I have removed my stupid HttpFilter:


public function filters()

    {

        return array(

            'https +new, payment',

        );

    }

And then I’m creating the CHtml::link using CController:createAbsoluteUrl like:


CHtml::link('Subscribe', $this->createAbsoluteUrl('subscription/new',array(),'https'))

And also using it in the last redirect to close the secure connection.


$this->redirect($this->createAbsoluteUrl('subscription/complete',array(),'http'));

Thanks, Pablo.

Just want to ask, isn’t it better and faster to use .htaccess in forcing https?

Many thanks

Thanks I also followed the guide on www.jaburo.net/?p=40

But ended up using .htaccess due to it not working and my lack of time to learn/debug. Im also using Yii User, RSBAC and Bootstrap so im guessing my default controller isnt whats driving the ship.


RewriteEngine On

RewriteCond %{SERVER_PORT} 80

RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

:blink:

Hi guys,

I follow the guild link. 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.

According to my research.

All pages better to use protocol Ssl. Because the session key will transmitted on to other pages.

If the pages do not transmitted information securely, will cause a user session to be stolen

I found a mixture of www.jaburo.net/?p=40 and yii’s filter guide was the best solution as I wanted to redirect to HTTPS only on my proper server, whilst on my test server i wanted to keep with HTTP since I didn’t have a proper SSL.

I defined the following in the main.php config (under params):

‘force_https’ => TRUE,

This is my HTTPS Filter (stored under protected/filters):




class HttpsFilter extends CFilter

{

	public $bypass = FALSE;


	protected function preFilter( $filterChain )

	{

		if((!Yii::app()->getRequest()->isSecureConnection) && (!$this->bypass))

		{

			# 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;

    }

}



then in the Controller I have:




	public function filters()

	{

		return array(

			array(

				'application.filters.HttpsFilter + login',

				'bypass' => !Yii::app()->params['force_https'],

			),

		);

	}



With the above approach, I can have a different config file on the main server and test server and if force_https is TRUE, it will redirect my login page, otherwise it will just skip through this validator.