yii2登录重定向后丢失用户身份

时间:2015-01-26 17:55:34

标签: redirect identity yii2

我已经查看了其他类似的问题,虽然这个问题(Yii2 user identity loss after page redirection)提出了几乎相同的问题,但没有适用于我的情况的解决方案。

我创建了一个新的标识类,我已经实现了所有必要的方法并实现了IdentityInterface。请注意,它不会扩展ActiveRecord,而是扩展我自己的基本Model类,它不是从AR派生的。

一切似乎都运行良好,我可以登录并进行正确的身份验证。我已经跟踪了代码,我可以看到在IdentityInterface :: validatePassword()和User :: login()被调用之后,我在Yii :: $ app->用户中正确设置了我的身份类。

但是,一旦登录成功并且用户被重定向,Yii :: $ app-> user包含一个空的IdentityInterface,而不是重定向之前的那个。

在SiteController :: actionLogin()中,我修改了以下代码:

return $this->goHome();

为:

$tmp = $this->goHome();
// echo '<pre>';var_dump(Yii::$app->user);echo '</pre>';exit;
return($tmp);

我可以看到Yii :: $ app-&gt;用户在return()语句之前仍然具有正确的标识。

谁能告诉我为什么我会失去我的身份?我已经追踪了我能想到的一切:yii \ web \ Controller,yii \ base \ Controller,yii \ web \ Response,SiteController,yii \ web \ User等...

任何帮助都会非常感激。谢谢!

5 个答案:

答案 0 :(得分:3)

同样的问题,3天后找到解决方案,我工作。 我的用户模型是:

namespace app\models;

use Yii;
class User extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
{
    public $username;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'tbl_users';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['name', 'email', 'password'], 'required'],
            [['email'], 'unique'],
            [['role', 'status'], 'integer'],
            [['created', 'last_update'], 'safe'],
            [['name', 'email', 'password'], 'string', 'max' => 250]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'name' => 'Name',
            'email' => 'Email',
            'password' => 'Password',
            'role' => 'Role',
            'status' => 'Status',
            'created' => 'Created',
            'last_update' => 'Last Update',
        ];
    }
    public function getAuthKey() {

    }

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

    public function validateAuthKey($authKey) {

    }

    public static function findIdentity($id) {

    }

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

    }
    public static function findByEmail($email)
    {
        return static::findOne(array('email'=>$email));
    }

    public function validatePassword($password)
    {
        return $this->password === $password;
    }
}

我改变了:

public static function findIdentity($id) {

}

到:

public static function findIdentity($id) {
    return self::findOne(array('id'=>$id));
}

它为我工作。

答案 1 :(得分:2)

试试这个

  1. 为您的Active实施implements \yii\web\IdentityInterface 记录并实施\yii\web\IdentityInterface
  2. 中的所有方法
  3. 在您的班级中将$ users声明为private static $users = [];的静态变量。
  4. 更改findByUsername()功能以获取用户名称的用户详细信息。 在配置文件中添加

    &#39;用户&#39; =&GT; [&#39; identityClass&#39; =&GT; &#39; app \ models \ active record class&#39;,  &#39; enableAutoLogin&#39; =&GT;真正,   ],

    class User extends \yii\db\ActiveRecord                                     
    implements\yii\web\IdentityInterface {
    
    private $_user = false;
    public $rememberMe = true;
    /*
     * static variable
     */
    private static $users = [];
    
    /**
     * @inheritdoc
     */
    public static function tableName() {
        return 'user';
    }
    
    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['username', 'email', 'password', 'loginType'], 'required'],
    
        ];
    }
    
    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'id' => Yii::t('app', 'ID'),
            'username' => Yii::t('app', 'Username'),
    
            'email' => Yii::t('app', 'Email'),
            'password' => Yii::t('app', '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);
        } else {
            return false;
        }
    }
    
    /**
     * Finds user by [[username]]
     *
     * @return User|null
     */
    public function getUser() {
        if ($this->_user === false) {
            $this->_user = self::findByUsername($this->username);
        }
    
        return $this->_user;
    }
    
    public function validatePassword($password) {
        if ($this->password == md5($password)) {
            return true;
        }
        return false;
    }
    
    public static function findIdentity($id) {
        return static::findOne($id);
    }
    
    public static function findIdentityByAccessToken($token, $type = null) {
        return static::findOne(['access_token' => $token]);
    }
    
    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) {
        /*
         * Get Record from Usertable
         */
        $user = User::findOne(["username" => $username]);
        if (!empty($user)) {
            /* Create array with your active record like below */
            $identity_use = ['id' => $user['id'],
                'username' => $user['username'],
                'password' => $user['password'],
                'authKey' => '',
                'accessToken' =>'',];
            return new static($identity_use);
        }
        return null;
    }
    

    }

答案 2 :(得分:2)

我遇到了同样的问题。我有我的自定义类实现yii \ web \ IdentityInterface。我确保会话已启用且enableAutologin也是如此,但我根本没有运气。

最后,我意识到在config / web.php中有一个设置&#39;用户&#39; =&GT; [&#39; identityClass&#39; =&GT; &#39; app \ models \ User&#39;,&#39; enableAutoLogin&#39; =&GT;真]

当然,identityClass是基本yii应用程序中的默认值。将此值设置为我的自定义类后,最终会保留标识。

答案 3 :(得分:2)

可能导致会话丢失的另一个简单错误是调用

$this->redirect(...);

而不是

return $this->redirect(...);

由于Yii在此方法中未调用die()exit(),因此将执行重定向后行上的代码。习惯了CodeIgniter,我已经假设了这一点,花了几天的时间才弄明白。

答案 4 :(得分:-1)

我希望这可以帮到你

<?php

namespace app\models;

use Yii;

class User extends \yii\db\ActiveRecord implements      \yii\web\IdentityInterface {

private $_notification;

public static function tableName()
{
    return 'users';
}

public function setNotification($n) {
    Yii::$app->session['user_' .$this->id . '_notification'] = $n;
}

public function getNotification() {
    $n = Yii::$app->session['user_' .$this->id . '_notification'];
    Yii::$app->session['user_' .$this->id . '_notification'] = NULL;
    return $n;
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['email', 'password', 'first_name'], 'required'],
        [['role'], 'integer'],
        [['email', 'first_name'], 'string', 'max' => 128],
        [['password'], 'string', 'max' => 32]
    ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'id' => 'ID',
        'email' => 'E-mail',
        'password' => 'Пароль',
        'first_name' => 'Имя',
        'role' => 'Роль',
    ];
}

public static function findByEmail($email) {
    return self::find()->where(['email' => $email])->one();
}

public function validatePassword($password) {
    if ($this->password == md5($password)) {
        return true;
    }
    return false;
}

public static function findIdentity($id)
{
    return static::findOne($id);
}

public static function findIdentityByAccessToken($token, $type = null)
{
    return static::findOne(['access_token' => $token]);
}

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

public function getAuthKey()
{
    return $this->authkey;
}

public function validateAuthKey($authKey)
{
    return $this->authkey === $authKey;
}

}