Yii 2 IdentityInterface data is lost after redirect

I have created my Yii 2 application. In my database there is a table user having the following fields: firstName, lastName, username and password, ‘authKey’.

Using Gii tool I created a model for the user table. In order to implement login functionality, I extended this class from IdentityInterface and I implemented all methods. Here is method list:




 public static function findIdentityByAccessToken($token, $type = null)

    {

    	throw new NotSupportedException();

    }

    

      public static function findIdentity($id)

    {

    	Admin::findOne($id)

    }

    

    public function getId()

    {

    	return this->id;

    }

    

 	public function getAuthKey()

    {

    	return $this->authKey

    }

    

    

 	public function validateAuthKey($authKey)

    {

    	return $this->authKey = $authKey;

    }

    

    public static function findByUsername($username)

    {

    	return static::find(array('username'=>$username));

    }

    

    public function validatePassword($password) {

    	return $this->password == $password;//Just for demonstration purposes

    }

I changed my config file (user component to be equal to this):




  'user' => [

    	'identityClass' => 'app\models\Admin',

    	'enableAutoLogin' => true,

    ],

In LoginController, after line


    if($model->load(Yii::$app->request->post()) && $model->login()) {

I print


    var_dump(Yii::$app->user->identity);exit;

user identity property, and the vlaues are set normally. As soon as I redirect user to any other page


var_dump(Yii::$app->user->identity); exit;

is equal to null.

Can someone explain me what is happening?

You have to return.

But, why "Admin::findOne($id)" rather than "static::findOne($id)" ?

Is this class "Admin"?

Hello Folks !!

Pretty strange problem is happening here. After successful login,when user is redirecting to another page of application


Yii::$app->user->identity 

is getting null.

Anyone can suggest a proposed solution for this issue.

Hello Softark !!

it seems everything is fine in my model class. But still the same issue exist. Could you please explain what could be an issue here.

I meant to say that you should write:




public static function findIdentity($id)

{

    return self::findOne($id)

}



@codesutra: I couldn’t reproduce the issue. It might be a problem with the session component.

[color="#006400"]/* topics merged */[/color]

@softark, Happy new year !!

And below is my code from web.php




'session' => [

    		'class' => 'yii\web\DbSession',

    		// 'db' => 'mydb',  // the application component ID of the DB connection. Defaults to 'db'.

    		// 'sessionTable' => 'my_session', // session table name. Defaults to 'session'.

    	],

        'cache' => [

            'class' => 'yii\caching\FileCache',

        ],

        'user' => [

            'identityClass' => 'app\models\User',

            'enableAutoLogin' => true,

        	'enableSession'	=>true,

        ],



Is anything missing in my session component or user component configuration ?

Thanks & Regards,

@codesutra, Happy New Year!!

I don’t see nothing strange in your config.

Could you show us the code of app\models\User ?

Here is my code for user model.




<?php


namespace app\models;


use yii\db\ActiveRecord;

use yii\web\IdentityInterface;


/**

 * This is the model class for table "tbl_user".

 *

 * @property integer $id

 * @property string $username

 * @property string $password

 * @property string $first_name

 * @property string $last_name

 * @property string $email

 * @property integer $active

 * @property string $last_login

 */

class User extends ActiveRecord implements IdentityInterface

{

    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return 'tbl_user';

    }


    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['username', 'password', 'first_name', 'last_name', 'email'], 'required'],

            [['active'], 'integer'],

            [['last_login'], 'safe'],

            [['username', 'email'], 'string', 'max' => 128],

            [['password'], 'string', 'max' => 255],

            [['first_name', 'last_name'], 'string', 'max' => 150],

            [['username'], 'unique']

        ];

    }


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'id' => 'ID',

            'username' => 'Username',

            'password' => 'Password',

            'first_name' => 'First Name',

            'last_name' => 'Last Name',

            'email' => 'Email',

            'active' => 'Active',

            'last_login' => 'Last Login',

        ];

    }

    

   /** Finds an identity by the given ID.

    *

    * @param string|integer $id the ID to be looked for

    * @return IdentityInterface|null the identity object that matches the given ID.

    */

    public static function findIdentity($id)

    {

    	return static::findOne($id);

    }

    

    /**

     * Finds an identity by the given token.

     *

     * @param string $token the token to be looked for

     * @return IdentityInterface|null the identity object that matches the given token.

     */

    public static function findIdentityByAccessToken($token, $type = null)

    {

    	//return static::findOne(['access_token' => $token]);

    }

    

    /**

     * @return int|string current user ID

     */

    public function getId()

    {

    	return $this->id;

    }

    

    

    /**

     * @return string current user auth key

     */

    public function getAuthKey()

    {

    	//return $this->auth_key;

    }

    

    /**

     * @param string $authKey

     * @return boolean if auth key is valid for current user

     */

    public function validateAuthKey($authKey)

    {

    	//return $this->getAuthKey() === $authKey;

    }

    

 }



And here is my code for LoginForm




<?php


namespace app\models;


use Yii;

use yii\base\Model;


/**

 * LoginForm is the model behind the login form.

 */

class LoginForm extends Model

{

    public $username;

    public $password;

    public $rememberMe = true;


    private $_user = false;




    /**

     * @return array the validation rules.

     */

    public function rules()

    {

        return [

            // username and password are both required

            [['username', 'password'], 'required'],

            // rememberMe must be a boolean value

            ['rememberMe', 'boolean'],

            // password is validated by validatePassword()

            ['password', 'validatePassword'],

        ];

    }


    /**

     * Validates the password.

     * This method serves as the inline validation for password.

     *

     * @param string $attribute the attribute currently being validated

     * @param array $params the additional name-value pairs given in the rule

     */

    public function validatePassword($attribute, $params)

    {

        if (!$this->hasErrors()) {

            $user = $this->getUser();


            if (!$user || !$user->validatePassword($this->password)) {

                $this->addError($attribute, 'Incorrect username or password.');

            }

        }

    }


    /**

     * Logs in a user using the provided username and password.

     * @return boolean whether the user is logged in successfully

     */

    public function login()

    {

        if ($this->validate()) {

            return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);

        }

        return false;

    }


    /**

     * Finds user by [[username]]

     *

     * @return User|null

     */

    public function getUser()

    {

        if ($this->_user === false) {

            $this->_user = User::findOne(['username'=>  $this->username]); //User::findByUsername($this->username);

        }


        return $this->_user;

    }

}




And here is my code from Login method.




   public function actionLogin()

    {

    	$this->layout = "login";

    	

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

            //return $this->goHome();

            $this->redirect(['index']);

        }


        $model = new LoginForm();

        if ($model->load(Yii::$app->request->post()) && $model->login()) {

            //return $this->goBack();

        	$this->redirect(['index']);

        }

        return $this->render('login', [

            'model' => $model,

        ]);

    }



I tried the same LoginForm.php and User.php file with different yii2 basic application there it is working perfectly fine. I’m not able to figure it out that where is a loop whole?

Do you ‘session’ table in database?

How can you login if there is no validatePassword() method in User model?

I have validate password method in my model.but I didn’t paste it here :). I’ll paste that method as well.

Hey guys !!

Anyone can suggest something here ?

Thanks & Regards,

I assume you have got ‘session’ table in database. Why there is no return in here




        if ($model->load(Yii::$app->request->post()) && $model->login()) {

            //return $this->goBack();

                $this->redirect(['index']);

        }



or did you not paste it as well?

Anything in logs?

Thanks Bizley for your reply. yes session is stored in database. And as i think return is not mandatory here in above pasted code.

Also, i didn’t find anything strange in logs as well.

As @Bizley has pointed out, this actionLogin will always render ‘login’ view, because it doesn’t return the redirection response.

http://www.yiiframework.com/doc-2.0/guide-runtime-responses.html#browser-redirection

Thank you softark for your reply.But i don’t think that it is a redirection issue.As I believe and did a debug it is an issue with login method available in LoginForm model.




 /**

     * Logs in a user using the provided username and password.

     * @return boolean whether the user is logged in successfully

     */

    public function login()

    {

        if ($this->validate()) {

            return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);

        }

        return false;

    }




BTW i changed a code in login action from SiteController as give below. but nothing worked here. And redirection is working absolutely fine here.




if ($model->load(Yii::$app->request->post()) && $model->login()) {

            return $this->goBack();

}



Yii::$app->user->login method is not able to hold user identity after a redirection.Even i refresh a page after redirection it loose a user identity and send back user to login page.I hope it will make some scene here.

Thank & Regards,

:unsure:

I would do line-by-line tracing using my favorite PHPStorm with XDebug.

Codesutra: you keep skipping the issue with the redirect!

You need to [size="5"]return[/size] the redirect.

Glad to know that thank you :)

Thanks jacome for your input here. This is how my current login action is looking in SiteController




    public function actionLogin()

    {

    	$this->layout = "login";

    	      


        $model = new LoginForm();

        if ($model->load(Yii::$app->request->post()) && $model->login()) {

            //return $this->goBack();

           return $this->redirect(['index']);

        }

        return $this->render('login', [

            'model' => $model,

        ]);

    }



Am i doing something wrong here ? Since, still my issue has not fixed.

Thanks & Regards,

Waiting a good news from you.