Home Page Displayed As Guest After Succesful Login Until Refresh

Hello guys, I have a quick question.

I noticed that after logging in to my yii application I get correctly redirected to my home page, but its appereance is the same of what guest users see before logging in (ie. the “login” link at top right is there). However if I refresh the page by pressing f5 everything is displayed correctly and the “bug” doesn’t return anytime until next login.

A side note: this has happened me in Firefox 26.0 (the latest afaik) but not on Google Chrome. I didn’t try IE since I’ve decided to discourage the use of the app with it.

Has this happened to anyone before? Any code I can add to help your thoughts about it? It’s a minor bug but still… ::)

Thanks in advance to whoever will help, cheers!

It sounds like a caching issue. Make sure your web server isn’t caching your PHP pages.

I’m testing it with XAMPP locally, should I check its conf files about caching?

Hmm, a bit more searching suggests that it’s unlikely that the PHP output is being cached by the web server.

Out of interest, can you show the code you’re using to perform the redirect. Also, can you show the headers that are being sent on the request for the front page (using your browser’s developer tools)?

This is the controller managing login (part of the User module, not modified)


<?php


class LoginController extends Controller

{

	public $defaultAction = 'login';


	/**

	 * Displays the login page

	 */

	public function actionLogin()

	{

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

			$model=new UserLogin;

			// collect user input data

			if(isset($_POST['UserLogin']))

			{

				$model->attributes=$_POST['UserLogin'];

				// validate user input and redirect to previous page if valid

				if($model->validate()) {

					$this->lastViset();

					if (Yii::app()->user->returnUrl=='/index.php')

						$this->redirect(Yii::app()->controller->module->returnUrl);

					else

						$this->redirect(Yii::app()->user->returnUrl);

				}

			}

			// display the login form

			$this->render('/user/login',array('model'=>$model));

		} else

			$this->redirect(Yii::app()->controller->module->returnUrl);

	}

	

	private function lastViset() {

		$lastVisit = User::model()->notsafe()->findByPk(Yii::app()->user->id);

		$lastVisit->lastvisit = time();

		$lastVisit->save();

	}


}

And these are the headers:

Does the log in happen in the call to $model->validate()?

$model->validate() refers to the UserLogin class, which again refers to the authenticate() method of UserIdentity. There the control is performed.

Userlogin.php


<?php


/**

 * LoginForm class.

 * LoginForm is the data structure for keeping

 * user login form data. It is used by the 'login' action of 'SiteController'.

 */

class UserLogin extends CFormModel

{

	public $username;

	public $password;

	public $rememberMe;


	/**

	 * Declares the validation rules.

	 * The rules state that username and password are required,

	 * and password needs to be authenticated.

	 */

	public function rules()

	{

		return array(

			// username and password are required

			array('username, password', 'required'),

			// rememberMe needs to be a boolean

			array('rememberMe', 'boolean'),

			// password needs to be authenticated

			array('password', 'authenticate'),

		);

	}


	/**

	 * Declares attribute labels.

	 */

	public function attributeLabels()

	{

		return array(

			'rememberMe'=>UserModule::t("Remember me next time"),

			'username'=>UserModule::t("username or email"),

			'password'=>UserModule::t("password"),

		);

	}


	/**

	 * Authenticates the password.

	 * This is the 'authenticate' validator as declared in rules().

	 */

	public function authenticate($attribute,$params)

	{

		if(!$this->hasErrors())  // we only want to authenticate when no input errors

		{

			$identity=new UserIdentity($this->username,$this->password);

			$identity->authenticate();

			switch($identity->errorCode)

			{

				case UserIdentity::ERROR_NONE:

					$duration=$this->rememberMe ? Yii::app()->controller->module->rememberMeTime : 0;

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

					break;

				case UserIdentity::ERROR_EMAIL_INVALID:

					$this->addError("username",UserModule::t("Email is incorrect."));

					break;

				case UserIdentity::ERROR_USERNAME_INVALID:

					$this->addError("username",UserModule::t("Username is incorrect."));

					break;

				case UserIdentity::ERROR_STATUS_NOTACTIV:

					$this->addError("status",UserModule::t("You account is not activated."));

					break;

				case UserIdentity::ERROR_STATUS_BAN:

					$this->addError("status",UserModule::t("You account is blocked."));

					break;

				case UserIdentity::ERROR_PASSWORD_INVALID:

					$this->addError("password",UserModule::t("Password is incorrect."));

					break;

			}

		}

	}

}



and UserIdentity.php


<?php


/**

 * UserIdentity represents the data needed to identity a user.

 * It contains the authentication method that checks if the provided

 * data can identity the user.

 */

class UserIdentity extends CUserIdentity

{

	private $_id;

	const ERROR_EMAIL_INVALID=3;

	const ERROR_STATUS_NOTACTIV=4;

	const ERROR_STATUS_BAN=5;

	/**

	 * Authenticates a user.

	 * The example implementation makes sure if the username and password

	 * are both 'demo'.

	 * In practical applications, this should be changed to authenticate

	 * against some persistent user identity storage (e.g. database).

	 * @return boolean whether authentication succeeds.

	 */


        //with the following method the db is checked

	public function authenticate()

	{

		if (strpos($this->username,"@")) {

			$user=User::model()->notsafe()->findByAttributes(array('email'=>$this->username));

		} else {

			$user=User::model()->notsafe()->findByAttributes(array('username'=>$this->username));

		}

		if($user===null)

			if (strpos($this->username,"@")) {

				$this->errorCode=self::ERROR_EMAIL_INVALID;

			} else {

				$this->errorCode=self::ERROR_USERNAME_INVALID;

			}

		else if(Yii::app()->getModule('user')->encrypting($this->password)!==$user->password)

			$this->errorCode=self::ERROR_PASSWORD_INVALID;

		else if($user->status==0&&Yii::app()->getModule('user')->loginNotActiv==false)

			$this->errorCode=self::ERROR_STATUS_NOTACTIV;

		else if($user->status==-1)

			$this->errorCode=self::ERROR_STATUS_BAN;

		else {

			$this->_id=$user->id;

			$this->username=$user->username;

			$this->errorCode=self::ERROR_NONE;

		}

		return !$this->errorCode;

	}

    

    /**

    * @return integer the ID of the user record

    */

	public function getId()

	{

		return $this->_id;

	}

}

EDIT: maybe the user class can be of help :) :


<?php


class WebUser extends RWebUser

{


    public function getRole()

    {

        return $this->getState('__role');

    }

    

    public function getId()

    {

        return $this->getState('__id') ? $this->getState('__id') : 0;

    }


//    protected function beforeLogin($id, $states, $fromCookie)

//    {

//        parent::beforeLogin($id, $states, $fromCookie);

//

//        $model = new UserLoginStats();

//        $model->attributes = array(

//            'user_id' => $id,

//            'ip' => ip2long(Yii::app()->request->getUserHostAddress())

//        );

//        $model->save();

//

//        return true;

//    }


    public function afterLogin($fromCookie)

	{

        //imposta lo schema relativo al cliente a cui appartiene l'utente

        Yii::app()->session['userSchema'] = Yii::app()->session['tablePrefix'] = Yii::app()->session['cliente'] = $this->getUserSchema();


        parent::afterLogin($fromCookie);

        //$this->updateSession();

        //aggiornamento di sessione disattivato in quanto non vengono attualmente gestiti i profile

	}


    public function updateSession() {

        $user = Yii::app()->getModule('user')->user($this->id);

        $userAttributes = CMap::mergeArray(array(

                                                'email'=>$user->email,

                                                'username'=>$user->username,

                                                'create_at'=>$user->create_at,

                                                'lastvisit_at'=>$user->lastvisit_at,

                                           ),$user->profile->getAttributes());

        foreach ($userAttributes as $attrName=>$attrValue) {

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

        }

    }


    public function model($id=0) {

        return Yii::app()->getModule('user')->user($id);

    }


    public function user($id=0) {

        return $this->model($id);

    }


    public function getUserByName($username) {

        return Yii::app()->getModule('user')->getUserByName($username);

    }


    public function getAdmins() {

        return Yii::app()->getModule('user')->getAdmins();

    }


    public function isAdmin() {

        return Yii::app()->getModule('user')->isAdmin();

    }

   //this is a custom method I made, don't mind it

    public function getUserSchema(){

    $user =  User::model()->findByPk(Yii::app()->user->id);

    return $user->userschema;

  }


}

I’m not sure what the problem is. Does the same thing happen both when you choose “Remember Me” and when you don’t?

Just to make sure that the user isn’t logged in, try adding this to your home page temporarily:




<?= Yii::app()->user->isGuest ? 'Guest' : 'Logged In'; ?>



What does that show after the redirection?

EDIT:

Also, it would be worth testing in IE, just to see whether it exhibits the same problem.

Tried and it displays “Guest” after the redirect, but after I refresh it becomes “Logged In”. The thing is, the user is logged but the home page seem not to notice it until further requests. A bit weird… Also, Chrome doesn’t have this issue at all (always displays “Logged In” correctly).

EDIT: testing in IE then, just a sec

EDIT2: IE behaves correctly. Looks like it happens only in FF. :)

EDIT3: about the “Remember Me” functionality, I don’t use it and I removed even the checkbox in the login form since I want the users to retype their login each time they start a new session. So I guess that’s not influencing?

Out of interest, what happens if you try to log in in a private browsing window (or whatever Firefox calls it)?

This is probably shared by the normal FF navigation aswell: first login goes well, "Logged in" as expected. However, logging off and in again causes the same issue (user logged but Yii::app()->user->isGuest returning true the first time). At this point I would suspect it might be cache-related.

That’s very strange. Try clearing all of your browser’s cache and cookies.

EDIT:

Also, try disabling any Firefox add-ons, in case something is conflicting.

ANOTHER EDIT:

Does any of the information on this page help?

Checking your tests out, updating later with results :) thank you for your time already

EDIT: Safe mode doesn’t change anything, in fact the restart doesn’t even cause logout which makes me think the session is kept. Clearing cache, cookies and logins doesn’t help either.

I found out that the only way to have a "first time login" display "Logged In" correctly is to close the browser window. After doing that, the first login will work as intended. Any other login after the first one will display the guest appearance after the redirect.

Maybe some strange behaviour between yii session and FF session? Looking further, luckily this isn’t project-breaking :) again, thanks for your time until now.

I know it’s an old thread but I was just debugging this and found the source of the issue. It’s YiiDebugToolbarRoute - the pretty extension. I have just figured out that this is one of the differences between mine and production environment (where the bug doesn’t happen). I will check how it “traps” the session cookie first time, before page refreshes.

I got the same problem. After success authenticate i’m guest.

On my host ended free space on storage disk LOL.