How To Use Https For The Loginurl

I want to redirect users to a login page if they aren’t already logged in. Yii sorts this all out for me. My question is whether I can redirect someone to the https version of the login page?

The Yii documentation at http://www.yiiframework.com/doc/guide/1.1/en/topics.auth#role-based-access-control has all the instructions.

In my controller I have:




    ...


    public function filters()

    {

        return array('accessControl');

    }


    public function accessRules()

    {

        return array(

            array('allow',      // Allow all actions for logged in users ("@")

                'users'     => array('@'),

                'actions'   => array('index'),

            ),

            array('deny'),      // Deny anything else

        );

    }


    ...



Yii uses the [font="Courier New"]loginUrl[/font] property of the [font="Courier New"]user[/font] component to determine where to redirect unauthorized users. By default, [font="Courier New"]loginUrl[/font] points to the [font="Courier New"]site/login[/font] page. It can be configured e.g.




array(

    ......

    'components'=>array(

        'user'=>array(

            // this is actually the default value

            'loginUrl'=>array('site/login'),

        ),

    ),

)



My options:

[list=1]

[*]Use a absolute url e.g. [font=“Courier New”]‘https://www.example.com/site/login[/font]’. This is annoying because then I have to have the correct value for each of our sites, local, staging, production, etc.

[*]Leave the default and then ensure the login page has a filter that redirects to https. This is what we do at the moment but it means we have 2 redirects and the Google pagespeed suggestion tool is recommending I shorten my redirect chain.

[/list]

Is there a better way?

I don’t particularly like it, but maybe you could use something like:




'loginUrl'=>"https://{$_SERVER['SERVER_NAME']}/site/login",



It seems pretty fragile to me though, because it depends on the index.php being hidden and other things.

A better option might be to extend CWebUser with your own class. You could include a constructor with something like this:




    public function __construct()

    {

        $this->loginUrl = Yii::app()->createAbsoluteUrl('/site/login', array(), 'https');

    }



You’d just need to update the config to point to this class:




    'components'=>array(

        'user'=>array(

            'class'=>'WebUser',

        ),

    ),



You should look up through the inheritance chain to make sure you call any parent constructor.

Thanks Keith, your idea worked perfectly.




class WebUser extends CWebUser

{

    ...


    /**

     * Initializes the application component.

     * This method overrides the parent implementation by setting the loginUrl property.

     */

    public function init()

    {

        parent::init();


        // Set the login url that Yii uses in the accessControl filter to redirect non-authorised users.

        // This way we can take users to the SSL login page directly and shorten the redirect chain.

        $this->loginUrl = Yii::app()->createAbsoluteUrl('/site/login', array(), 'https');

    }