我已经查看了其他类似的问题,虽然这个问题(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等...
任何帮助都会非常感激。谢谢!
答案 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)
试试这个
implements \yii\web\IdentityInterface
记录并实施\yii\web\IdentityInterface
。private static $users = [];
的静态变量。更改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;
}
}