Different default controllers for guest and authorized users

Hi there!

If you need to display different versions of the index page (i.e. use different controllers), depending on whether a user is a guest or not, you may use the following code: (add this to config/main.php)




	'onBeginRequest' => function () {

		if (!Yii::app()->user->isGuest) {

			Yii::app()->defaultController = 'dashboard';

		}

	},

good tip!

:)

I guess I should mention that this will not work on PHP < 5.3

Anyway, all progressive coders are already on 5.3 branch ;) Anonymous functions alone are well worth it

Since this only changes the defaultController, it appears that this can be easily overridden with a simple URL.

For Example: mysite?r=site/index

Does anyone know of a more robust method of creating and using a GuestController for a guest user?

@nwap is right…I need to know a more robust way too!!!

Nwap, you may use access filters to force the needed behaviour

@tedd,could you please give a practical example with access filters to force the needed behavior…

like your default controller trips…

thanks

bipu

As nwap noticed, a guest user can easily access DashboardController by simply typing "index.php?r=dashboard/index". The solution is to forbid access of unauthorized users to DashboardController by using access filters:


class DashboardController extends Controller 

{

  public function filters ()

  {

    return array(

      'accessControl',    

    );

  }


  public function accessRules ()

  {

    // allow only authenticated users

    return array(

      array('allow',

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

      ),

      array('deny',

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

      ),

    );

  }


  /** the rest of the code */


}

tedd,

I think your suggestion is Yii’s “standard” solution

However, I am trying to setup a webapp where only a few select pages are accessible by ‘Guest’. The rest require an authorized user for access.

I’d like a solution that satisfies the following goals:

  1. If I forget to do something (such as update the accessRules() method on a new controller), I want the safe default behavior. In other words deny access to ‘Guest’.

  2. If access is denied to ‘Guest’, I want Yii to redirect to the login page instead of showing an error.

I’ve come up with a solution that satisfies these goals, but since I’m very new to Yii, I’m looking for feedback and/or suggestions from the Yii community.

Here are the changes that I made:

In the array returned by ‘protected/config/main.php’, I added a params[‘publicPages’] entry:




'params'=>array(

	...

	// List of public pages that can be accessed without authentication.

	// All other pages will result in a redirect to the login page.

	'publicPages'=>array(

		'site/login',

		'site/error',

	),

),



In ‘protected/components/Controller.php’, I overrode the runActionWithFilters() method:




/**

 * Runs an action with the specified filters.

 * Extends the CController::runActionWithFilters() function.

 * If a Guest user is trying to access a non-public page, then redirect to the login page.

 * @param CAction $action the action to be executed.

 * @param array $filters list of filters to be applied to the action.

 */

public function runActionWithFilters($action,$filters)

{

	$params=Yii::app()->params;

	if(isset($params) && isset($params['publicPages']))

	{

		$route="{$this->id}/{$action->id}";

		if (!in_array($route, $params['publicPages']))

		{

			if (Yii::app()->user->isGuest)

			{

				Yii::app()->user->loginRequired();

				return;

			}

		}

	}

	parent::runActionWithFilters($action,$filters);

}



Seems to work for me on v1.1.7 and v1.1.8 – Please comment.

This solution seems not be robust as it requires to set pages which should be given access.

In my point of view, Access rules are best

http://www.yiiframework.com/forum/index.php?/topic/18854-different-default-controllers-for-guest-and-authorized-users/page__view__findpost__p__109372

the second solution is that, in each action, we need to check is it allowed for the current user





public function actionIndex(){

if(Yii::app()->user->IsGuest){

    $this->redirect('site/login');

}

}




PeRoChAk,

However, that is the whole point. As stated in my #1 goal, for websites where most of the pages require some type of authorization, I want the default behavior to block all pages without having to write the same code in every controller and/or every action.

I do not understand how using access rules satisfies my original #1 goal:

Just use inheritance.

I did use inheritance.

http://www.yiiframework.com/forum/index.php?/topic/18854-different-default-controllers-for-guest-and-authorized-users/page__view__findpost__p__111541

I did this. I have also enabled pretty URLs too.

Now when I login I get dashboard in the URL <sitename>/index.php. How do I get the page <sitename>/dashboard as the default page when user logs in?