Yii2 - пользовательская проверка с запросом к БД

Я пытаюсь заставить эту пользовательскую проверку работать, но в данный момент ничего не получаю. В чем проблема?

['password', function($attribute, $params){

                $password = \Yii::$app->db
                    ->createCommand("SELECT * FROM forbiddenPasswords WHERE password = '{$params}'")
                    ->queryOne();

                if($password)
                    $this->addError($attribute, 'This password is forbidden. Please try another.');
            }],

person Sasha    schedule 26.01.2016    source источник


Ответы (3)


  • $params содержит параметры валидатора, а не атрибут,
  • вы должны правильно связать параметр в своем запросе.

e.g. :

$count = Yii::$app->db->createCommand('SELECT COUNT(*) FROM forbiddenPasswords WHERE password = :password')
    ->bindValue(':password', $this->password)
    ->queryScalar();

if($count)
    $this->addError($attribute, 'This password is forbidden. Please try another.');

Или вы можете создать модель ActiveRecord для forbiddenPasswords и использовать unique< /a> валидатор, чтобы сделать то же самое...

person soju    schedule 26.01.2016

Я проверил, что переменная {$params} предназначена для дополнительных значений. И если вы хотите проверить пароль, назначьте значение, подобное этому.

 ['password', function($attribute, $params){

           $pass=$this->password;
            $password = \Yii::$app->db
                ->createCommand("SELECT * FROM forbiddenPasswords WHERE password = '{$pass}'")
                ->queryOne();

            if($password)
                $this->addError($attribute, 'This password is forbidden. Please try another.');
        }],
person Anamika Shrivastava    schedule 26.01.2016

Не пишите открытый валидатор пароля. Это небезопасно!

В Yii2 вы можете использовать validatePassword метод Security компонент.

Сначала сохраните в базе данных хэш пароля методом setPassword:

/**
 *
 * @param string $password WARNING! OPEN PASSWORD!
 */
public function setPassword($password)
{
    $this->password_hash = Yii::$app->security->generatePasswordHash($password);
}

В модели у вас должен быть метод validatePassword:

/**
 * @param string $password WARNING! OPEN PASSWORD!
 *
 * @return boolean
 */
public function validatePassword($password)
{
    return Yii::$app->security->validatePassword($password, $this->password_hash);
}

Или, если вы хотите использовать модель User в качестве формы, вы можете написать это:

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        ...
        ['password', 'validatePassword']
    ];
}

/**
 * @param string $attribute attribute name
 * @param array $params Additional params
 */
public function validatePassword($attribute, $params)
{
    if (Yii::$app->security->validatePassword($this->$attribute, $this->password_hash) == false) {
        $this->addError($attribute, Yii::t('frontend', 'Incorrect password'));
    }
}
person Onedev_Link    schedule 26.01.2016
comment
Ну, вопрос не совсем о хэше пароля. - person soju; 26.01.2016
comment
@soju Вас не беспокоят незашифрованные пароли? - person Onedev_Link; 26.01.2016
comment
где вы видите незашифрованные пароли (кроме таблицы запрещенных паролей, но это не проблема) ?? - person soju; 26.01.2016
comment
@soju Ты прав. Это моя паранойя. Надеюсь под password подразумевается hashed password. - person Onedev_Link; 26.01.2016
comment
Не волнуйтесь, быть параноиком — это хорошо, когда вы веб-разработчик :) - person soju; 26.01.2016
comment
@ Onedev.Link Я открою вам секрет некоторых крупных ИТ-компаний, хранящих пароли в нехешированном виде. И password здесь не зашифровано, так как оно только что пришло от POST. И да, паранойя иногда хороша. - person ineersa; 26.01.2016
comment
У меня есть таблица запрещенных паролей. Я не вижу смысла хешировать что-то общедоступное (я использую для этого список твиттера и дропбокса). Эта таблица никак не связана с пользователем. Пароль пользователя хэшируется. Пользователю не разрешено использовать пароль, найденный в таблице, вот и все. - person Sasha; 26.01.2016