Yii, лучший способ реализовать " изменение пароля пользователя"
Я использую Yii для приложения, я пишу очень простое управление пользователями, например, регистрацию, удаление и обновление пользователей... Для обновления существующего пользователя мне нужно сначала проверить старый пароль, прежде чем изменить его на новый вставленный пароль. Итак, вот поля, которые у меня есть в форме:
username:----
old_password:---
new_password:---
и моя таблица выглядит так:
id, username, password
Как я могу проверить старый_пароль новый_пароль до его обновления? Я знаю обычное PHP-кодирование, но я хотите знать, есть ли какие-либо трюки Yii, которые делают это автоматически...
спасибо заранее
3 ответов
его просто создать action
это имеет логику для прохождения обновления.
сделать мишень для form
новые action
в этом случае actionChangePass
и validate
там, как вы хотите .
примерный пример можно поставить так
public function actionChangePass($id)
{
$user = loadModel($id)
if(md5($_POST['User']['old_password']) === $user->password)
{
$user->setScenario('changePassword');
$user->attributes = $_POST['User'];
$user->password = md5($_POST['User']['new_password']);
if($user->save())
Yii::app()->user->setFlash('passChanged', 'Your password has been changed <strong>successfully</strong>.');
}
else
{
Yii::app()->user->setFlash('passChangeError', 'Your password was not changed because it did not matched the <strong>old password</strong>.');
}
}
также убедитесь, что у вас есть $old_password в вашем пользователе User
Model
. Также вы можете сделать некоторые проверки в правилах модели, чтобы сделать новый пароль
могут быть и другие способы, но я это делаю такой
также создайте свою пользовательскую проверку scenario
changePassword
- вы не должны загрязнять модели с мусором. Пожалуйста, всегда имейте в виду эти основные принципы MVC:
- ваш контроллер не должен знать о реализации вашей модели.
- не загрязняйте свою модель вещами, не связанными с бизнес-моделью вашего приложения.
всегда создавайте многоразовый код, сделайте свой код " сухим "(не повторяйтесь)
кстати, какова цель поля username? Поскольку форма будет доступен только зарегистрированному пользователю, имя пользователя можно получить уже с помощью Yii:: app()->user.
<?php
// models/ChangePasswordForm.php
class ChangePasswordForm extends CFormModel
{
/**
* @var string
*/
public $currentPassword;
/**
* @var string
*/
public $newPassword;
/**
* @var string
*/
public $newPasswordRepeat;
/**
* Validation rules for this form.
*
* @return array
*/
public function rules()
{
return array(
array('currentPassword, newPassword, newPasswordRepeat', 'required'),
array('currentPassword', 'validateCurrentPassword', 'message'=>'This is not your password.'),
array('newPassword', 'compare', 'compareAttribute'=>'validateNewPassword'),
array('newPassword', 'match', 'pattern'=>'/^[a-z0-9_\-]{5,}/i', 'message'=>'Your password does not meet our password complexity policy.'),
);
}
/**
* I don't know your hashing policy, so I assume it's simple MD5 hashing method.
*
* @return string Hashed password
*/
protected function createPasswordHash($password)
{
return md5($password);
}
/**
* I don't know how you access user's password as well.
*
* @return string
*/
protected function getUserPassword()
{
return Yii::app()->user->password;
}
/**
* Saves the new password.
*/
public function saveNewPassword()
{
$user = UserModel::findByPk(Yii::app()->user->username);
$user->password = $this->createPasswordHash($this->newPassword);
$user->update();
}
/**
* Validates current password.
*
* @return bool Is password valid
*/
public function validateCurrentPassword()
{
return $this->createPasswordHash($this->currentPassword) == $this->getUserPassword();
}
}
пример действия контроллера:
public function actionChangePassword()
{
$model=new ChangePasswordForm();
if (isset($_POST['ChangePasswordForm'])) {
$model->setAttributes($_POST['ChangePasswordForm']);
if ($model->validate()) {
$model->save();
// you can redirect here
}
}
$this->render('changePasswordTemplate', array('model'=>$model));
}
пример кода шаблона:
<?php echo CHtml::errorSummary($model); ?>
<div class="row">
<?php echo CHtml::activeLabel($model,'currentPassword'); ?>
<?php echo CHtml::activePasswordField($model,'currentPassword') ?>
</div>
<div class="row">
<?php echo CHtml::activeLabel($model,'newPassword'); ?>
<?php echo CHtml::activePasswordField($model,'newPassword') ?>
</div>
<div class="row">
<?php echo CHtml::activeLabel($model,'newPasswordRepeat'); ?>
<?php echo CHtml::activePasswordField($model,'newPasswordRepeat') ?>
</div>
<div class="row submit">
<?php echo CHtml::submitButton('Change password'); ?>
</div>
<?php echo CHtml::endForm(); ?>
</div><!-- form -->
шаблон должен быть достаточно простым для создания. Этот код с некоторыми незначительными изменениями готов к копированию и вставке в другой проект Yii.
вот что мне лично нравится. Это сложная версия. Добавить в модель два поля, которые помогут вам обработать пароль. Обратите внимание, эти два поля не существует в базе данных и нет в Гии сгенерированный код. Что-то вроде
class UserModel extends CActiveRecord
{
/*Password attributes*/
public $initial_password;
public $repeat_password;
//..................
}
в форме не связывайте фактическое поле пароля в базе данных с каким-либо вводом. Два поля в базе данных должны быть связаны с этими двумя полями. Краткая версия формы становится:
<?php echo $form->errorSummary($model); ?>
<?php echo $form->passwordFieldRow($model,'initial_password',array('class'=>'span5','maxlength'=>128)); ?>
<?php echo $form->passwordFieldRow($model,'repeat_password',array('class'=>'span5','maxlength'=>128)); ?>
Теперь, как я знаю, что пользователь изменил пароль? Я просто проверяю beforeSave (), если два поля пусты, и сравниваю их, а затем меняю пароль. Если они пусты, я просто пропускаю все целиком. Поэтому простая версия beforeSave:
/**
* Called before saving the model
*/
protected function beforeSave()
{
if(parent::beforeSave())
{
if($this->isNewRecord)
{
$this->password = HashYourPass($this->initial_password);
}
else
{
//should we update password?
if($this->initial_password !== '')
{
//encrypt password and assign to password field
$this->password = HashYourPass($this->initial_password);
//Check old password match here
}
}
return true;
}
else
return false;
}
Теперь по вашему вопросу, одна вещь отсутствует. Проверка старого пароля! Вы можете добавить новые поля модели под названием aold password и элемент управления вводом формы. Затем в метод значение beforesave (как указано комментарием) вы можете сравнить ввод с фактическим полем пароля из базы данных, и если они совпадают, то измените пароль.
вы можете добавить их в качестве правил проверки со сценариями, но я нашел это сложным как-то и с небольшим временем под рукой я пошел с этим методом.