Separate logins for app and module

I built an admin module in my app, for which I want to create a separate authentication system from the one that is used for my global app users. User authentication on the admin module is also independent from the global app’s authentication, the login info isn’t even stored in the same model or DB table. It should therefore be possible to be logged into the global app as one user, and to the admin module as another user, concurrently.

Basically, I want to be able to access something like this in my module:




$appUser = Yii::app()->user;

$modUser = Yii::app()->controller->module->user;



Any ideas on making this work?

admin app, frontend app~~

Not affect each other

The module does interact with the app, only its login system is different. So separating them completely is not really an option.

I am not sure if a concurrent login is possible because a new session would be spawned when you login as admin. However, you could use two tabs in your browser to move between the two sessions.

If you extend your site controllers from SiteController, you could include a login method for handling site logins. This method would launch the module used to handle normal logins. Then create another base controller (e.g., AdminController) and extend it from SiteController. Then you can override the login method in SiteController with another login method for handling the admin login. Your other admin controllers could then be extended from AdminController.

in admin module, your can use


Yii::app()->user->setStateKeyPrefix('xxx');

in init method~

and logout a bit modification:


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

change to


Yii::app()->user->logout(false);

Just an idea, never implemented it, but could you solve that with different cookie paths for main/admin section? If that works you’d have 2 independent sessions, i think.

Yii::app()->user->setStateKeyPrefix(‘xxx’);

this is what you want~

hi,here is my solution:

you want separated user as app and module.you must be separated the session.

so you need change you session keyprefix in the module class at the init function like this:

if($this->hasComponent(‘user’)){

$this->getComponent(‘user’)->setStateKeyPrefix(md5($this->name));

}

it is works. but the accessControl dosn’t works. beacase in CAccessControlFilter the user is fixed by app user;

so i think you can create a CModuleAccessControlFilter like CAccessControlFilter.

change app()->user to app()->controller->module-user;

to user this class you also need to create CModuleController extends CController

and rewrite the function filterAccessControl.

change

$filter=new CAccessControlFilter;

to

$filter=new CModuleAccessControlFilter;

I’ve created one ACL class for the Customer module and define the logics of the acl there.

and in the Component/Controller.php add this action, and everything access controll management bind in the CustomerAcl class. you can also define the settings in the database for the access control or you can set the in the

configuration array as well.


public function beforeAction($action)

	{

		$cACL = new CustomerACL;

		$cACL->processACL();

		return true;

	}

/protected/components/CustomerACL.php




<?php

class CustomerACL extends CController

{

	/**

	 * controller and action structure all in small case

	 * [*] contains all actions and [,] comma delimite multiple actions.

	 * @var unknown_type

	 */

	public $auth_urls = array();


	public function __construct()

	{

		$this->auth_urls = array(

		array('controller' => 'cart', 'action'=>'checkout'),

		array('controller' => 'orders', 'action'=>'confirm,orderReview'),

		array('controller' => 'payment', 'action'=>'*'),

		array('controller' => 'menu', 'action'=>'menudetail', 'menudetail'=> array('ajax_popup'=>1)),

		);

	}


	public function isFollowACL($controller)

	{

		foreach ($this->auth_urls as $url) {

			if(strcasecmp($controller, $url['controller'])==0) {

				return true;

			}

		}

		return false;

	}


	public function isAuthUrl($controller, $action, $params=array())

	{

		$flag = false;

		foreach ($this->auth_urls as $url) {

			if(strcasecmp($controller, $url['controller'])==0) {

				switch($url['action']) {

					case '*':

						$flag = true;

						break;

					default:

						$actions = explode(',',$url['action']);

						if(in_array(strtolower($action), $actions)) 	$flag = true;

						foreach($actions as $actionName) {

							if($action == $actionName && isset($url[$actionName])) {

								$flagC=0;

								foreach($url[$actionName] as $key => $value) {

									if(isset($_REQUEST[$key]) && $value == $_REQUEST[$key]) {

										$flagC++;

									}

								}

								if($flagC == count($url[$actionName])) $flag=true; 

								else $flag = false;

							} 

						}

						break;

				}

			}

		}

		return $flag;

	}

	public function processACL()

	{

		$request = yii::app()->request;

		

		$controller  	= Yii::app()->controller->id;

		$action  		= Yii::app()->controller->action->id;

		

		if($this->isFollowACL($controller)) {

			if($this->isAuthUrl($controller, $action)) {

				if(Yii::app()->customer->id) {

					return true;

				}else {

					//store url in stack

					Yii::app()->customer->setState('cutomer_back_login_url',Yii::app()->request->getUrl());

					

					if(Yii::app()->request->getParam('ajax_popup')) {

						$url = Yii::app()->customer->loginUrl;

						$url[0].= '/login/popup/1';

						$this->redirect($url);

					}else {

						$this->redirect(Yii::app()->customer->loginUrl);

					}

				}

			}

		}else {

			return true;

		}

	}

}

it works great for me and i can play with this in the module

:)