I want to allow user login from two different model.
Config.php
'user' => [
'identityClass' => 'app\models\User', //one more class here
'enableAutoLogin' => false,
'authTimeout' => 3600*2,
],
LoginForm.php
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'],
];
}
public function validatePassword($attribute, $params)
{
if (!$this->hasErrors()) {
$user = $this->getUser();
if (!$user || !$user->validatePassword($this->password)) {
$this->addError($attribute, Yii::t('user', 'Incorrect username or password.'));
}
}
}
public function login()
{
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
} else {
return false;
}
}
public function parentLogin()
{
// How to validate parent Login?
}
public function getUser()
{
if ($this->_user === false) {
$this->_user = User::findByUsername($this->username);
}
return $this->_user;
}
User.php
class User extends \yii\db\ActiveRecord implements IdentityInterface
{
public static function tableName()
{
return 'users';
}
public static function findIdentity($id)
{
return static::findOne($id);
}
public static function findByUsername($username)
{
return static::findOne(['user_login_id' => $username]);
}
Controller.php
public function actionLogin()
{
// Working
}
public function actionParentLogin()
{
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->parentLogin()) {
$parent = ParentLogin::find()->where(['p_username' => $model->p_username])->one();
if($parent){
\Yii::$app->session->set('p_id',$parent->p_id);
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,
]);
}
I don't know how to validate parent login. I tried for hours finding workaround but not succeed.
I am stuck on Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
because user table don't have parent login records.
My questions
1) Is it possible to have two identityClass
. If yes then how?
2) Is it possible to extend ParentLogin
model to User
. If yes then how to validate?
References
How To extend user class?
Customising the CWebUser class
Custom userIdentity class in yii2
Joe Miller has a good sugestion about having one user class and some boolean fields in users' table to check user's role, as an alternative to rbac. But since in your situation it is not possible, here is what I can suggest to you (this approach is half-way tested and need to be adopted).
Yes you can have two or more identityClasses, but not in the same time. You need to handle switching between identities. So first, I suggest to you edit your
LoginForm
model a little:Now in controller:
Your
parentLogin
model should extendsUser
model to make all this work:Now when you logged in, you need to handle identity switch, because in the configuration you have
'identityClass' => 'app\models\User'
. We can usebootstrap
property for that:IdentitySwitcher class:
** Edit, this doesn't work, you can only have one identity class ** ** Ref https://github.com/yiisoft/yii2/issues/5134 ** I would suggest trying the following - not tested.
In your config, add an extra identity interface, as you suggest;
Your
Parent
model can then either extend theUser
model, which will give the same validation methods as the originalUser
model, or implementIdentityInterface
from scratch. From your column names in yourparent
table, I'd suggest the second method as the columns are different to theUser
table.You would then need two
loginForms
:loginForm
andparentLoginForm
, as the validation is different in each case.Then, in your controller, you can call the appropriate login form as required.