Yii::app()->user->isGuest always returns true even

2019-04-21 05:33发布

I started to make some differences between those users which have authenticated and those that not. For this, i am using

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

However, in a determined view i put the following code:

<?php 
    if(Yii::app()->user->isGuest) {
        print("Welcome back Guest!");
        print("Your id is ".Yii::app()->user->id);
    } else {
        print("Welcome back ".Yii::app()->user->name);
        print("Your id is ".Yii::app()->user->id);
}?>

And i always get the "welcome back guest!", whether i have logged in (successfully) or not. And if i have logged in, then it displays the welcome message together with the user's id!

EDIT

@briiC.lv Hey.. sorry for the late reply, I hope you are still following this! I am not extending the given UserIdentity class. Is this mandatory? Since i still dont get very well the whole authorization issue, i thought it would be best to give a try with the class they provide, and then extend with my own functionality.. Anyway, next i post my UserIdentity class with its small tweaks.. maybe the problem lies here??

<?php class UserIdentity extends CUserIdentity{
private $_id;

public function authenticate()
{   
    $user = Users::model()->findAll('username=\''.$this->username.'\' AND password=\''.$this->encryptedPassword.'\'');
    if(!isset($user[0]))
    {
        return false;
    }
    else 
    {   
        $this->setState('id', $user[0]->id);            
        $this->username = $user[0]->username;
        $this->errorCode=self::ERROR_NONE;
        return true;
    }
}

public function getId()
{
    return $this->_id;
}

}

Here is the output i got when i started to log as you suggested; i got this output immediately after successfully logging in.

[05:23:21.833][trace][vardump] CWebUser#1 ( 
[allowAutoLogin] => true 
[guestName] => 'Guest' 
[loginUrl] => array ( '0' => '/site/login' ) 
[identityCookie] => null 
[authTimeout] => null 
[autoRenewCookie] => false 
[autoUpdateFlash] => true 
[CWebUser:_keyPrefix] => '0f4431ceed8f17883650835e575b504b' 
[CWebUser:_access] => array() 
[behaviors] => array() 
[CApplicationComponent:_initialized] => true 
[CComponent:_e] => null 
[CComponent:_m] => null 
)

Any help is much appreciated!

8条回答
爷、活的狠高调
2楼-- · 2019-04-21 06:09

First of all, you need to know condition that sets guest and logged-in user apart.

Based on Yii master's branch CWebUser::getIsGuest():

public function getIsGuest()
{
    return $this->getState('__id')===null;
}

Compared to your code:

$user = Users::model()->findAll('username=\''.$this->username.'\' AND password=\''.$this->encryptedPassword.'\'');
if(!isset($user[0])) {
    // false
} else {   
    $this->setState('id', $user[0]->id); // this is for persistent state sakes
    ...
}

}

In short: you did supply 'id' to Identity persistent state but Yii CWebUser expecting '__id' based on UserIdentity::getId().

Solution is pretty dead simple. You just need to set $this->_id

$user = Users::model()->findAll('username=\''.$this->username.'\' AND password=\''.$this->encryptedPassword.'\'');
if(!isset($user[0])) {
    // false
} else {   
    $this->setState('id', $user[0]->id); // this is for persistent state sakes
    $this->_id = $user[0]->id; // this is UserIdentity's ID that'll be fetch by CWebUser
    ...
}

}

This routine explains how CWebUser get UserIdentity's ID: https://github.com/yiisoft/yii/blob/master/framework/web/auth/CWebUser.php#L221

Please do test it out.

查看更多
Explosion°爆炸
3楼-- · 2019-04-21 06:15

Maybe you can try to debug harder: change messages to something like this:

if(Yii::app()->user->isGuest) {
    print("Not logged");
} else {
    print_r(Yii::app()->user);
    print("Welcome ".Yii::app()->user->name);
    print("Your id is ".Yii::app()->user->id);

}

And check session variable in your config/main.php file

...
    'session' => array(
        'autoStart'=>true,
    ),
...
查看更多
我只想做你的唯一
4楼-- · 2019-04-21 06:20

I have faced same problem and found that only one line in UserIdentity Component will resolve this issue.

This is your code:

else 
{   
    $this->setState('id', $user[0]->id);            
    $this->username = $user[0]->username;
    $this->errorCode=self::ERROR_NONE;
    return true;
}

Update this code by this one

else 
{
    $this->_id = $user[0]->id;   
    $this->setState('id', $user[0]->id);            
    $this->username = $user[0]->username;
    $this->errorCode=self::ERROR_NONE;
    return true;
}
查看更多
来,给爷笑一个
5楼-- · 2019-04-21 06:21

in PHP.INI => session.use_only_cookies = 0

查看更多
叼着烟拽天下
6楼-- · 2019-04-21 06:30

when you call authenticate function login user as

 $userIdentity = new UserIdentity($username, $password);   
        $userIdentity->authenticate();
        if ($userIdentity->errorCode===UserIdentity::ERROR_NONE) {
            Yii::app()->user->login($userIdentity,0);
 }

and fetch id as

echo 'id='.Yii::app()->user->getId();

apply this code and check

查看更多
该账号已被封号
7楼-- · 2019-04-21 06:30

Please try following code. Its working well

//config/main.php
return array (
'component' => array(
    'session' => array(
        'savePath' => INSTANCE_ROOT.DS.'runtime'.DS.'session',
        'autoStart' => true,
        ),
    )
);

// LoginController 
class LoginController extends CController {
    public function actionLogin () {
      if(isset($_POST['LoginForm']))
      {
          $form = new LoginForm;
          $form->setAttributes($_POST['LoginForm']);

          if ($form->validate()) {
                $user = Users::model()->find('upper(username) = :username', array(
                    ':username' => strtoupper($form->username)));

                    if($user)
                        return $this->authenticate($user, $form);
                    else {
                        Yii::log( 'som.....', 'error');
                        $form->addError('password', Yii::t('Username or Password is incorrect'));
                    }
                    return false;
          }
      }
    }

    protected function authenticate($user, $form) {
        $identity = new UserIdentity($user->username, $form->password);
        $identity->authenticate();
        switch($identity->errorCode) {
            case UserIdentity::ERROR_NONE:
                $duration = $form->rememberMe ? 3600*24*30 : 0; // 30 days
                Yii::app()->user->login($identity,$duration);
                return $user;
                break;
            case UserIdentity::ERROR_EMAIL_INVALID:
                $form->addError("password",Yii::t('Username or Password is incorrect'));
                break;
            case UserIdentity::ERROR_STATUS_INACTIVE:
                $form->addError("status",Yii::t('This account is not activated.'));
                break;
            case UserIdentity::ERROR_STATUS_BANNED:
                $form->addError("status",Yii::t('This account is blocked.'));
                break;
            case UserIdentity::ERROR_STATUS_REMOVED:
                $form->addError('status', Yii::t('Your account has been deleted.'));
                break;
            case UserIdentity::ERROR_PASSWORD_INVALID:
                Yii::log( Yii::t(
                            'Password invalid for user {username} (Ip-Address: {ip})', array(
                                '{ip}' => Yii::app()->request->getUserHostAddress(),
                                '{username}' => $form->username)), 'error');
                    if(!$form->hasErrors())
                    $form->addError("password",Yii::t('Username or Password is incorrect'));
                break;
                return false;
        }
    }
}

class UserIdentity extends CUserIdentity {

    const ERROR_EMAIL_INVALID=3;
    const ERROR_STATUS_INACTIVE=4;
    const ERROR_STATUS_BANNED=5;
    const ERROR_STATUS_REMOVED=6;
    const ERROR_STATUS_USER_DOES_NOT_EXIST=7;

    public function authenticate()
    {
        $user = Users::model()->find('username = :username', array(
                    ':username' => $this->username));
        if(!$user)
            return self::ERROR_STATUS_USER_DOES_NOT_EXIST;

        if(Users::encrypt($this->password)!==$user->password)
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else if($user->status == YumUser::STATUS_INACTIVE)
            $this->errorCode=self::ERROR_STATUS_INACTIVE;
        else if($user->status == YumUser::STATUS_BANNED)
            $this->errorCode=self::ERROR_STATUS_BANNED;
        else if($user->status == YumUser::STATUS_REMOVED)
            $this->errorCode=self::ERROR_STATUS_REMOVED;

        return !$this->errorCode;
    }
}

class Users extends CActiveModel
{
    const STATUS_INACTIVE = 0;
    const STATUS_ACTIVE = 1;
    const STATUS_BANNED = -1;
    const STATUS_REMOVED = -2;

    // some ..........

    public static function encrypt($string = "")
    {
        $salt = 'salt';
        $string = sprintf("%s%s%s", $salt, $string, $salt);
        return md5($string);
    }
}
查看更多
登录 后发表回答