User logs to the site, and has a cookie set for Remember me.
We have some state variables set against this user.
A. We do some changes on the site, like we introduce new state variables.
When the users are coming back, with their cookies active, they are recognized and logged in. But since their state doesn’t contain the new state variables, the system crashes with the following message:
[size=“2”][color="#454545"][font=“arial, helvetica, sans-serif”]‘CException’ with message ‘Property “PortalWebUser.login_type” is not[/font][/color][/size] [color="#454545"][font=“arial, helvetica, sans-serif”][size=“2”]defined.’ [/size][/font][/color]
So the question is, how to detect such exception, as when we detect such, we want to redirect the user to the logout page, so they must log in again.
class WebUser extends CWebUser
{
public $possibleStates = array(
'login_type',
'something_else',
);
public function init()
{
parent::init();
$this->verifyStates();
}
public function afterLogin($fromCookie)
{
$this->verifyStates();
}
public function verifyStates()
{
// Check if user is logged in and all $possibleStates are available.
// If one is not available, logout the user or load the state dynamically if possible.
}
}
/**
* This method is called after the user is successfully logged in. You may override this method to do some postprocessing (e.g. log the user login IP and time; load the user permission information).
* @param type $fromCookie
*/
public function afterLogin($fromCookie) {
parent::afterLogin($fromCookie);
if ($fromCookie) {
// we need to refresh user state variable
$user = user::model()->findByPk($this->id);
if (empty($user)) {
// user was not found in the database, perform logout
Yii::app()->controller->redirect('authorize/logout');
} else {
$user->saveState($this);//this is the key
}
}
$this->logUserLoginHistory();
}
Yes. You could do all the checking in init(), but you might want to do something different in case the user just logged in (instead of having an active session). This you can only do in afterLogin. CWebUser::init does makes sure afterLogin will be called, so in my example verifyStates would only be called once (if you stop the execution properly by redirecting the user).
For the case that everything is okay (user will not be redirected) you could add bool $statesVerified and set it to true to make sure the verification does not occur twice.
I have submodules like admin. And for some reason the admin login, triggers the front-end PortalWebUser class, and the verifyStates does run, and since they are different states on admin, it simply redirects the user to the logout link of the front-end.
Or within the custom webuser class you could check whether the module of the current controller is an instance of AdminModule (Yii::app()->controller->module).