A
A
Anton Natarov2016-04-09 14:02:54
Yii
Anton Natarov, 2016-04-09 14:02:54

Yii2: Login by email or username?

How can I implement login on different fields? Since the form shows either the username field or email. I would not like to leave it like that, validation happens normally, if the soap is empty, then it validates by name and vice versa. Now it looks like this.

public function getUser()
    {
        if ($this->_user === false) {
            $this->_user = User::findByUsername($this->username);
                      if ($this->_user === false) {
                                $this->_user = User::findByEmail($this->email);
                       }
        }
        return $this->_user;
    }

In ruls, email is the safe attribute.
Form in Views
<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>

                <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>

                <?= $form->field($model, 'email')->textInput() ?>

                <?= $form->field($model, 'password')->passwordInput() ?>

                <?= $form->field($model, 'rememberMe')->checkbox() ?>

                <div style="color:#999;margin:1em 0">
                     Я забыл пароль <?= Html::a('восстановить', ['password-reset-request']) ?>.
                </div>

                <div class="form-group">
                    <?= Html::submitButton('Вход', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
                </div>

            <?php ActiveForm::end(); ?>

I need one common field that would validate normally both by soap and by name. Perhaps I will change it to phone numbers and there will be my own input pattern. How to do the right thing?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
M
Maxim Fedorov, 2016-04-09
@HanDroid

If I correctly understood the task, and the goal is to enter either soap / or login / or phone number in one field, then what prevents you from doing this:
1. Make an attribute in the model, for example: $login and use it on the form
2. Write your own validator that will check if the data is phone / soap, etc.
https://yiiframework.com.ua/ru/doc/guide/2/input-v...
https://yiiframework.com.ua/ru/doc/guide/2/input-v...
3. In the getUser method, do a search for the entered data in the required fields through OR ?

M
Maxim Timofeev, 2016-04-09
@webinar

skipOnEmpty more details as always in the docs:
www.yiiframework.com/doc-2.0/yii-validators-valida...

M
Max Khartanovych, 2016-04-10
@maxkh

If you are doing all this in a model, the best solution would be to have a separate form where the rules () for validation and filtering would be written. In the same form, you can implement your authorization logic.

class Login extends Model
{
    public $identity;
    public $password;

    public function rules()
    {
        return [
            ['identity', 'filter', 'filter' => 'trim'],
            ['identity', 'required'],

            ['password', 'required'],
        ];
    }

    /**
     * @return bool|null|static|User
     */
    public function authenticate()
    {
        if (!$user = User::findIdentityByUsernameOrEmail($this->identity)) {
            $this->addError('identity', Yii::t('app', 'invalid_credentials_on_login'));
            return false;
        }

        if (!$user->validatePassword($this->password)) {
            $this->addError('identity', Yii::t('app', 'invalid_credentials_on_login'));
            return false;
        }

        return $user;
    }
}

/**
     * Finds user by username or email
     *
     * @param string $identity
     * @return static|null
     */
    public static function findIdentityByUsernameOrEmail($identity)
    {
        /**
         * Try to find identity by nickname
         * @var User $user
         */
        if ($user = static::findOne(['username' => $identity, 'status' => self::STATUS_ACTIVE])) {
            return $user;
        }

        /**
         * Try to find identity by email
         * @var LoginAccount $loginAccount
         */
        if ($loginAccount = LoginAccount::findByEmail($identity)) {
            return $loginAccount->getUser()->one();
        }

        return null;
    }

In my case, authorization by email or nickname in one field, which has the general name identity, and when searching for a user, I use 2 models, since email is in another table.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question