Session Management With Cwebuser::setstate Or Chttpsession

Hi all

What is the best solution on how to handle session, using CWebUser or CHttpSession? Currently i use CWebUser’s setState method, and i want to save user login info in CWebUser and then after some duration the session will expire. The problem is, when i test it, it goes well with firefox, but for some reason that i dont know, it won’t work with chrome.




class AbUserIdentity extends CUserIdentity 

{

	public $id;

	public $username;

	public $password;


        ...


	private function storeInfo($user) 

	{

		$this->setState('hasLogin', 	true);

		$this->setState('username', 	$user->uid);

		$this->setState('nickname', 	$user->unick);

		$this->setState('email', 			$user->umail);

		$this->setState('status', 		$user->ustat);

		$this->setState('lastLogin', 	date( 'Y-m-d H:i:s' ));

	}

}






class LoginForm extends CFormModel 

{

	public $username;

	public $password;

	// public $verifyCode;


        ...


	public function login() 

	{

		if ( $this->_identity->errorCode === ABUserIdentity::ERROR_NONE ) {

			$duration = 3600*3; // 3 hours

			Yii::app()->user->login( $this->_identity, $duration );


			return true;

		} else {

			return false;

		}

	}

}



What do you guys think?

Your approach is right I guess.

CWebUser::setState and CHttpSession are using the same $_SESSION mechanism.

That’s why it should working the same.

http://www.yiiframework.com/doc/api/1.1/CWebUser#setState-detail

http://www.yiiframework.com/doc/api/1.1/CHttpSession#get-detail

Here is fragment of my code. It’s working perfectly with FF, Chrome and other.




class WebUser extends CWebUser {

    private $_model = null;

    public function getModel(){

       if (!$this->isGuest && $this->_model === null){

           $this->_model = User::model()->findByPk($this->id);

       }

       return $this->_model;

    }

    protected function afterLogin($fromCookie) {

       $user = $this->getModel();

       foreach ($user->getAttributes() as $attrName=>$attrValue) {

          $this->setState($attrName,$attrValue);

       }

    }

}



I see. But if the two class use $_SESSION mechanism, makes me wonder if the other is another solution, i am probably wrong. Anyhow thanks a lot for pointing that out.

I also read something about cookie i think. Somehow i don’t understand yet. And also the login part


Yii::app()->user->login( $this->_identity, $duration );

The $duration is set but it’s like no duration at all in my ff

Oh sorry, why do i did a stupid mistake. Actually it work on my ff but not in my chrome. And here is cookie in the chrome browser

5011

chrome cookie.jpg

I highlight the line that i am suspicious about. Maybe that’s the cause?

What is login_theme cookie? Is it non default name for php session ID cookie?

Probably cpanel. But oh sorry my mistake actually this picture is my valid attachment

5012

chrome cookie 2.jpg

I see the expire based on $duration (3 hours). That aside, i am still trying to figure it out

setState method will put your data in the cookie.

You should have nothing in the cookie but the user id which is set by Yii using CWebUser::setId() and can be retrieved using CWebUser::getId() so this means you have no reason to use setState in the first place.

setState is used only if for example you use autologin and you want some data to be available in cookie when autologin happens, but again, having the user identifier in cookie is all you need to later query the database and have access to info.

You should use Yii::app()->session to store the user data, and you should hook into afterLogin method in order to populate user data from database into session.

Sure?

Very bravo explanation twisted1919, thank’s a lot :)

I will try this out quickly, especially afterLogin method, i dont realize the usage of afterLogin. I will post the result then.

Ha ha, right, i think i was thinking to CUserIdentity::setState ?

Anyway, Yii::app()->session is more straight forward than setState and avoids the above confusion in general. My thoughts still stands for the approach :)

I am little confuse here :) Maybe i should refresh my understanding about cookie and session first :)

Only session’s id stored in cookie, but data stored in files(db, redis & etc) at server.

You should read http://www.php.net/manual/en/book.session.php and http://www.yiiframework.com/doc/api/1.1/CHttpSession

How about CWebUser::setId(), do Yii set it automatically or do we should set it manually?

I dump Yii::app()->user->id after login action and it return NULL. but then i dump Yii::app()->isGuest and it return false.

Is it should return Not Null and false?

Yeah i am on it. Thank’s a lot for your helps :D

CWebUser gets ID from identity instance in login method automatically. https://github.com/yiisoft/yii/blob/1.1.14/framework/web/auth/CWebUser.php#L229.

You may override CUserIdentity::getId() in your identity implementation.

Hi guys, its been a loong time.

After took some times, i now knew how to solve this one. My problem actually was to get the login form appeared after some duration. After i read all your great responses, then i tried to tweak my codes with a couple of time and tests, i could see my desired result. After that i can share the results here as i promised.




//config.php

    ...


    'params' => array(

      // DB prefix

      'tablePrefix' => '',


      // Timeout

      'sessionTimeout' => 3600*3,

    ),

    ...



I forgot to show this class before





class AbBackController extends CController 

{

	public $layout='//layouts/column2';


	private $_assetBase;


        ...


	/**

	 * Handle Auth and Login Page

	 * 

	 * @param  CInlineAction $action

	 * @return boolean

	 */

	protected function beforeAction($action) 

	{

		$login_action = in_array($action->id, array('login','captcha'));

		$login_controller = $action->controller->id == 'site';


		if ( $login_controller && $login_action ) {

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

				if ( yii::app()->user->getState('sessionTimeout') < time() ) {

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

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

      	                        } else {

      		                        $this->redirectUrl( 'setting/index' );

      	                        }

			} else {

				Yii::app()->session['hasLogin']  = false;

			}

		} else {

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

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

			} else if ( yii::app()->user->getState('sessionTimeout') < time() ) {

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

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

    	                }

		}


		return parent::beforeAction($action);

	}


        ...

}






<?php


class LoginForm extends CFormModel 

{

	public $username;

	public $password;

	public $verifyCode;


	private $_identity;


        ...


	/**

	 * Logs in the user using the given username and password in the model.

	 *

	 * @return boolean whether login is successful

	 */

	public function login() 

	{

		if ( $this->_identity->errorCode === ABUserIdentity::ERROR_NONE ) {

			$duration = Yii::app()->params['sessionTimeout']; // 3 hours

			Yii::app()->user->login( $this->_identity, $duration );


			return true;

		} else {

			return false;

		}

	}

}



And that’s it. Thanks a lot to sleptor and twisted1919, you’re all great.