If you want to add module based login to a site without using RBAC, please follow these guidelines.
Consider the situation where we want to add 3 types of login in a site: customer, dealer, and admin.
Start by generating three modules using gii. (To do this, please refer to this guide for module generation http://yiiframework.com/doc/guide/1.1/en/basics.module#creating-module)
Step 1
Copy the UserIdentity component to the module/components folder for each module. We will validate each module against its table. For example, customer validation is done using customer table, and admin validation against the admin table
For each module, change its UserIdentity authenticate() function to perform the appropriate validation.
Step 2
For each module, add the following lines to its main page. For example, for the Customer module, add to Customer/CustomerModule.php Add the following lines to init():
$this->setComponents(array(
'errorHandler' => array(
'errorAction' => 'customer/default/error'),
'user' => array(
'class' => 'CWebUser',
'loginUrl' => Yii::app()->createUrl('customer/default/login'),
)
));
Yii::app()->user->setStateKeyPrefix('_customer');
Step 3
Create the login/logout action in each module's DefaultController.
For example, for the Customer module:
Create the actionLogin() in Customer/controllers/DefaultController.php.
Also, create actionLogout() as follows:
public function actionLogout() {
Yii::app()->user->logout(false);
$this->redirect(Yii::app()->getModule('customer')->user->loginUrl);
}
Point sub-domain to module
This tips from the forum URL Subdomain to module
There is a feature called "Parameterizing Hostnames" (described on this pages). add the following lines to main.php
'components' => array(
...
'urlManager' => array(
'rules' => array(
'http://customer.example.com' => 'customer/default/index',
'http://customer.example.com/login' => 'customer/default/login',
),
),
...
),
So "customer/default/index" refers to the module "customer" with controller "default" and action "index".
Update ¶
Redirect to respective module login, if user not logged in to a particular model
add following code to customer module CustomerModule.php in beforeControllerAction
if(Yii::app()->getModule('customer')->user->isGuest)
Yii::app()->getModule('customer')->user->setReturnUrl('customer/default/login');
do the same for other module
in SiteController's site/login method
public function actionLogin() {
Yii::app()->request->redirect(Yii::app()->createUrl(Yii::app()->user->returnUrl));
}
(or)
Update 2 (best method) ¶
Redirect to respective module login, if user not logged in to a particular model
add following code to customer module CustomerModule.php
public function beforeControllerAction($controller, $action) {
if (parent::beforeControllerAction($controller, $action)) {
// this method is called before any module controller action is performed
// you may place customized code here
$route = $controller->id . '/' . $action->id;
// echo $route;
$publicPages = array(
'default/login',
'default/error',
);
if (Yii::app()->user->isGuest && !in_array($route, $publicPages)){
Yii::app()->getModule('customer')->user->loginRequired();
}
else
return true;
}
else
return false;
}
do the same for other module
Thanks to ricardograna for sharing some configurations
Excellent
Particullary, I prefer to use module id, to make it more reusable
Yii::app()->user->setStateKeyPrefix("_{$this->id}");
Yii::app()->user->loginUrl = Yii::app()->createUrl("/{$this->id}/default/login");
And customize my UserIdentity (e.g. AdminIdentity, CustomeIdentity...etc) to avoid misunderstandings.
Thanks, thats all
If module has access rules is not required put redirect control on module, and it works ok only setting loginUrl and customize userIdentity in module.
Point sub-domain to module is not working
Point sub-domain to module is not working .
I am using YII framework at one of my project and I am facing problem with Parameterizing Host Names, I have a module "ADMIN" and I want to display this as a subdomain within my domain, so I am setting rules like the following way from the protected/config/main.php:
'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName'=>false,
'rules'=>array(
'<controller:w+>/<id:d+>'=>'/view',
'<controller:w+>/<action:w+>/<id:d+>'=>'/',
'<controller:w+>/<action:w+>'=>'/',
'www.admin.moresoccerfun.com/login' => 'admin/default/index',
),
),
But when I am running the page: www.admin.moresoccerfun.com/login from the browser, it is showing "SERVER NOT FOUND". Please help me out from this problem.
Thanks and looking for your response.
Problem setting errorHandler
Hi, I can't get errorHandler working when it is being set this way:
$this->setComponents(array(
'errorHandler' => array( 'errorAction' => 'customer/default/error'),
...
it works when I set it by:
Yii::app()->errorHandler->errorAction='customer/default/error';
I would like to handle module errors "inside" my module rather than using main app errorHandler. Am I missing something important?
problem when implement user level access
Please take a look to my problem. it working for me but create problem when implement user level access.
http://www.yiiframework.com/forum/index.php/topic/37991-module-based-login-and-user-level-acces-system
Properly Setting Yii::app()->user->returnURL
I modified Update 2 to set the returnURL before redirecting to the login page, so once a user logs in they can be sent to the original page they requested. I have also implemented the generic naming suggested by other posts. Thanks to all who contributed - it got me started on this concept very quickly.
public function beforeControllerAction($controller, $action) { if(parent::beforeControllerAction($controller, $action)) { // this method is called before any module controller action is performed // you may place customized code here $route = $controller->id . '/' . $action->id; $publicPages = array( 'default/login', 'default/error', ); if (Yii::app()->user->isGuest && !in_array($route, $publicPages)){ /*set the return URL*/ $request=Yii::app()->request->getUrl(); Yii::app()->user->returnURL=$request; /*redirect to module login form*/ Yii::app()->getModule("{$this->id}")->user->loginRequired(); } else return true; } else return false; }
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.