2012-11-05 33 views
7

Tôi đang sử dụng Yii cho một ứng dụng, tôi đang viết một quản lý người dùng rất đơn giản, như đăng ký, xóa và cập nhật người dùng ... cần phải kiểm tra mật khẩu cũ trước khi thay đổi mật khẩu mới. Vì vậy, đây là lĩnh vực tôi có trong các hình thức:Yii, cách tốt nhất để thực hiện "thay đổi mật khẩu người dùng"

username:---- 
old_password:--- 
new_password:--- 

và bảng người dùng của tôi trông như thế này:

id, username, password 

Làm thế nào tôi có thể xác nhận các old_password trước khi cập nhật nó với new_password? Tôi biết php mã hóa thông thường, nhưng tôi muốn biết nếu có bất kỳ thủ đoạn Yii mà thực hiện điều này tự động ...

Cảm ơn trước

+1

Bạn nên sử dụng lại khung xác thực hiện tại bất cứ khi nào có thể, bởi vì, thực sự, nó phức tạp. Ví dụ: hãy xem https://github.com/delight-im/PHP-Auth, cả hai đều không có khung công tác bất khả tri và không có cơ sở dữ liệu. – caw

Trả lời

4

của nó đơn giản tạo ra một action có logic để cập nhật qua.

Đặt mục tiêu cho form thành action mới trong trường hợp này actionChangePassvalidate theo cách bạn muốn.

Một ví dụ thô có thể được đặt như thế này

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>.');      
    } 
} 

Ngoài ra hãy chắc chắn rằng bạn có $ old_password trong sử dụng của bạn UserModel. Ngoài ra bạn có thể làm một số kiểm chứng thực trong các quy tắc của mô hình để làm cho mật khẩu mới cần

có thể có một số cách khác nhau quá, nhưng tôi làm điều đó như thế này

cũng tạo xác nhận tùy chỉnh của bạn scenariochangePassword

+1

Yên tĩnh Yiish. Đã bỏ phiếu! –

+0

Không thực sự ... Yiish sẽ tạo một Biểu mẫu mới và đặt tất cả logic vào đó – ThomasVdBerge

+0

@Stefano cảm ơn –

1

Đây là những gì Cá nhân tôi thích làm. Đây là một phiên bản phức tạp của việc này. Thêm vào mô hình hai trường sẽ giúp bạn xử lý mật khẩu. Lưu ý rằng hai trường này không tồn tại trong cơ sở dữ liệu và không có trong mã được tạo bởi Gii. Một cái gì đó như

class UserModel extends CActiveRecord 
{ 
    /*Password attributes*/ 
    public $initial_password; 
    public $repeat_password; 
    //.................. 
} 

Trong hình thức, đừng liên kết trường mật khẩu thực tế trong cơ sở dữ liệu với bất kỳ đầu vào. Hai trường trong cơ sở dữ liệu phải được liên kết với hai trường này. Phiên bản ngắn của biểu mẫu trở thành:

<?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)); ?> 

Làm cách nào để biết người dùng đã thay đổi mật khẩu? Tôi chỉ cần kiểm tra trong beforeSave() nếu hai trường trống và so sánh chúng và sau đó thay đổi mật khẩu. Nếu chúng trống rỗng thì tôi chỉ bỏ qua toàn bộ mọi thứ. Vì vậy, phiên bản đơn giản của beforeSave là:

/** 
    * 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; 
    } 

Bây giờ theo câu hỏi của bạn, một điều bị thiếu. Kiểm tra mật khẩu cũ! Bạn có thể thêm các trường Model mới được gọi là mật khẩu aold và điều khiển đầu vào biểu mẫu của nó. Sau đó, trong phương pháp beforesave (như được chỉ ra bởi bình luận), bạn có thể so sánh đầu vào với trường mật khẩu thực tế từ cơ sở dữ liệu và nếu chúng khớp nhau thì hãy thay đổi mật khẩu.

Bạn có thể thêm chúng dưới dạng quy tắc xác thực với các tình huống nhưng tôi thấy nó phức tạp bằng cách nào đó và với ít thời gian ở bàn tay tôi đã đi với phương pháp này.

9

Bạn không nên gây ô nhiễm mô hình của mình với rác.Vui lòng luôn ghi nhớ các nguyên tắc cơ bản về MVC này:

  • Bộ điều khiển của bạn không được biết về việc triển khai mô hình của bạn.
  • Đừng gây ô nhiễm mô hình của bạn với nội dung không được kết nối với mô hình kinh doanh của ứng dụng của bạn.

Luôn tạo mã tái sử dụng, làm cho mã của bạn "khô" (Đừng lặp lại chính mình)

Bằng cách này, mục đích của các lĩnh vực tên là gì? Vì biểu mẫu sẽ chỉ khả dụng cho người dùng đã đăng nhập, tên người dùng có thể được truy cập với 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(); 
    } 
} 

dụ controller action:

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)); 
} 

dụ mẫu mã:

<?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 --> 

Mẫu nên đủ dễ dàng để tạo ra. Mã này, với một số chỉnh sửa nhỏ, sẵn sàng để được sao chép & được dán vào một dự án Yii khác.

+0

Bạn có thể chia sẻ mã mẫu không? – AlphaMale

+0

Tôi đã cập nhật bài đăng với mã mẫu mẫu. Bạn nên làm theo hướng dẫn chính thức của Yii về cách quản lý biểu mẫu trong chế độ xem. –

Các vấn đề liên quan