Php 如何在yii2中使用两种不同的模型登录或切换标识类?
我想允许用户从两个不同的模型登录 Config.php LoginForm.php User.php Controller.php 我不知道如何验证家长登录。我花了几个小时寻找解决办法,但没有成功 我被困在Php 如何在yii2中使用两种不同的模型登录或切换标识类?,php,yii,yii2,yii2-basic-app,yii2-user,Php,Yii,Yii2,Yii2 Basic App,Yii2 User,我想允许用户从两个不同的模型登录 Config.php LoginForm.php User.php Controller.php 我不知道如何验证家长登录。我花了几个小时寻找解决办法,但没有成功 我被困在Yii::$app->user->login($this->getUser(),$this->rememberMe?3600*24*30:0)因为用户表没有父登录记录 我的问题 1) 是否可以有两个identityClass。如果是,那怎么办 2) 是否可以将ParentLogin模型扩展到U
Yii::$app->user->login($this->getUser(),$this->rememberMe?3600*24*30:0)代码>因为用户表没有父登录记录
我的问题
1) 是否可以有两个identityClass
。如果是,那怎么办
2) 是否可以将ParentLogin
模型扩展到User
。如果是,那么如何验证
参考资料
**编辑,这不起作用,您只能有一个标识类**
**参考号**
我建议尝试以下方法-未经测试
按照您的建议,在配置中添加一个额外的标识接口
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => false,
'authTimeout' => 3600*2,
],
'parent' => [
'identityClass' => 'app\models\Parent',
'enableAutoLogin' => false,
'authTimeout' => 3600*2,
],
然后,您的父级
模型可以扩展用户
模型,该模型将提供与原始用户
模型相同的验证方法,或者从头开始实现标识接口
。根据父表中的列名,我建议使用第二种方法,因为列与用户表不同
然后需要两个loginForms
:loginForm
和parentLoginForm
,因为每种情况下的验证都不同
然后,在控制器中,您可以根据需要调用相应的登录表单。Joe Miller提出了一个很好的建议,即在用户表中使用一个用户类和一些布尔字段来检查用户角色,作为rbac的替代方案。但由于在您的情况下,这是不可能的,因此我可以向您提出以下建议(这种方法经过了一半的测试,需要采用)
是的,您可以有两个或多个IdentityClass,但不能同时使用。您需要处理身份之间的切换。因此,首先,我建议您稍微编辑一下您的LoginForm
模型:
class LoginForm extends Model
{
public $username;
public $password;
public $rememberMe = true;
// we added this parameter to handle userModel class
// that is responsible for getting correct user
public $userModel;
private $_user = false;
/* all other methods stay same */
/**
* Finds user by [[username]]
*
* @return User|null
*/
public function getUser()
{
if ($this->_user === false) {
// calling findByUsername method dynamically
$this->_user = call_user_func(
[$this->userModel, 'findByUsername'],
$this->username
);
}
return $this->_user;
}
}
现在在控制器中:
public function actionParentLogin()
{
$model = new LoginForm(['userModel' => ParentLogin::className()]);
// calling model->login() here as we usually do
if ($model->load(Yii::$app->request->post()) && $model->login()) {
// no need to worry about checking if we found parent it's all done polymorphycally for us in LoginForm
// here is the trick, since we loggin in via parentLogin action we set this session variable.
Yii::$app->session->set('isParent', true);
return $this->redirect(['parent-dashboard']);
} else {
Yii::$app->getSession()->setFlash('error', Yii::t('site', 'Incorrect username or password.'));
}
}
return $this->render('parent-login', [
'model' => $model,
]);
}
您的parentLogin
模型应该扩展User
模型以使所有这些工作正常:
class parentLogin extends User
{
public static function tableName()
{
//you parent users table name
return 'parent_users';
}
public static function findByUsername($username)
{
return static::findOne(['p_username' => $username]);
}
}
现在,当您登录时,您需要处理标识切换,因为在配置中您有'identityClass'=>'app\models\User'
。我们可以使用bootstrap
属性:
//in your config file
'bootstrap' => [
'log',
//component for switching identities
'app\components\IdentitySwitcher'
],
IdentitySwitcher类:
class IdentitySwitcher extends Component implements BootstrapInterface
{
public function bootstrap($app)
{
//we set this in parentLogin action
//so if we loggin in as a parent user it will be true
if ($app->session->get('isParent')) {
$app->user->identityClass = 'app\models\ParentLogin';
}
}
}
您是否已经尝试在User.php中扩展您想要的类?@GuilhermeLopes。我试过了,但没有成功。所以,回滚更改。我总是这样做。。。我使用默认模型,并使用findOne的GuilhermeLopes修改默认模型的函数。你能详细说明一下吗。我花了半天的时间来解决这个问题。我不明白为什么你需要两个单独的桌子和模型来解决这个问题。为什么不在user
表中添加一个extra列,将其称为isParent并将其设置为boolean
。然后你可以测试它是否正确,做一些事情,如果它是错误的,做一些其他的事情。然后,您只需使用一个模型、一组验证和两个视图,具体取决于isParent
的值,我已经尝试过了,它不会起作用。它给出了第一个“缺少类”错误,添加后给出了标识错误。是的,刚刚发现这不起作用,只支持一个标识类。我会把这个放在这里,让人们知道它不起作用!谢谢@托尼。检查它。好的,让我知道它是如何进行的。config
中用于切换标识的组件是什么。对不起,没有得到它。您需要创建一个类。在本例中,我称之为IdentitySwitcher
。所以您需要创建一个目录组件,并在其中创建IdentitySwitcher.php文件,其中包含来自示例的内容
public function actionParentLogin()
{
$model = new LoginForm(['userModel' => ParentLogin::className()]);
// calling model->login() here as we usually do
if ($model->load(Yii::$app->request->post()) && $model->login()) {
// no need to worry about checking if we found parent it's all done polymorphycally for us in LoginForm
// here is the trick, since we loggin in via parentLogin action we set this session variable.
Yii::$app->session->set('isParent', true);
return $this->redirect(['parent-dashboard']);
} else {
Yii::$app->getSession()->setFlash('error', Yii::t('site', 'Incorrect username or password.'));
}
}
return $this->render('parent-login', [
'model' => $model,
]);
}
class parentLogin extends User
{
public static function tableName()
{
//you parent users table name
return 'parent_users';
}
public static function findByUsername($username)
{
return static::findOne(['p_username' => $username]);
}
}
//in your config file
'bootstrap' => [
'log',
//component for switching identities
'app\components\IdentitySwitcher'
],
class IdentitySwitcher extends Component implements BootstrapInterface
{
public function bootstrap($app)
{
//we set this in parentLogin action
//so if we loggin in as a parent user it will be true
if ($app->session->get('isParent')) {
$app->user->identityClass = 'app\models\ParentLogin';
}
}
}