有没有更好的方法来使用Auth更改cakephp中的用户密码?

时间:2010-05-19 19:20:31

标签: cakephp

我自己在学习cakephp。我试图创建一个带有changepassword功能的用户控制器。它有效,但我不确定这是否是最好的方法,我无法在这方面搜索有用的教程。 这是我的代码:

class UsersController extends AppController {

    var $name = 'Users';

    function login() {
    }

    function logout() {
        $this->redirect($this->Auth->logout());
    }

    function changepassword() {
        $session=$this->Session->read();
        $id=$session['Auth']['User']['id'];
        $user=$this->User->find('first',array('conditions' => array('id' => $id)));
        $this->set('user',$user);
        if (!empty($this->data)) {
            if ($this->Auth->password($this->data['User']['password'])==$user['User']['password']) {
                if ($this->data['User']['passwordn']==$this->data['User']['password2']) {
                // Passwords match, continue processing
                $data=$this->data;
                $this->data=$user;
                $this->data['User']['password']=$this->Auth->password($data['User']['passwordn']);
                $this->User->id=$id;
                $this->User->save($this->data);
                $this->Session->setFlash('Password changed.');
                $this->redirect(array('controller'=>'Toners','action' => 'index'));
                } else {
                    $this->Session->setFlash('New passwords differ.');
                    }
            } else {
                $this->Session->setFlash('Typed passwords did not match.');
            }
        }
    }
}

密码是旧密码,passwordn是新密码,password2是新密码。 还有其他的,更多的coomon方式在蛋糕中做到这一点吗?

4 个答案:

答案 0 :(得分:29)

我看到您在控制器中验证和操作数据。在模型中执行此操作通常是更好的做法。几天前我实现了类似的功能。我的change_password()方法看起来有点像这样:

# app/controllers/users_controller.php
function change_password() {
    if (!empty($this->data)) {
        if ($this->User->save($this->data)) {
            $this->Session->setFlash('Password has been changed.');
            // call $this->redirect() here
        } else {
            $this->Session->setFlash('Password could not be changed.');
        }
    } else {
        $this->data = $this->User->findById($this->Auth->user('id'));
    }
}

这是与该方法一起使用的视图的精简版本:

# app/views/users/change_password.ctp
echo $this->Form->create('User');
echo $this->Form->input('id');
echo $this->Form->input('current_password');
echo $this->Form->input('password1');
echo $this->Form->input('password2');
echo $this->Form->end('Submit');

做一些有趣事情的代码在模型中。我将表单中的字段添加到validate属性并写入custom validation methods。这允许我在应用程序的任何其他位置使用password1和password2字段,例如,在注册表单上。

# app/models/user.php
var $validate = array(
    'current_password' => array(
        'rule' => 'checkCurrentPassword',
        'message' => '...'
    ),
    'password1' => array(
        'rule' => 'checkPasswordStrength',
        'message' => '...',
    ),
    'password2' => array(
        'rule' => 'passwordsMatch',
        'message' => '...',
    )
);

最后,在模型的beforeSave()回调中,我将password设置为password1的哈希,以准备将数据存储在数据库中。

答案 1 :(得分:21)

迈克提供的解决方案很棒,但他省略了“checkCurrentPassword”功能。以下是您可以在模型中放置的函数示例:

# app/models/user.php
public function checkCurrentPassword($data) {
    $this->id = AuthComponent::user('id');
    $password = $this->field('password');
    return(AuthComponent::password($data['current_password']) == $password);
}

此解决方案从Auth组件获取当前用户ID,并将模型更改为指向该特定用户。然后,它将表单上输入的current_password的哈希值与为该用户存储的哈希密码进行比较。

此外,这里是您可以用来散列新密码的beforeSave函数:

# app/models/user.php
public function beforeSave($options = array()) {
    if (isset($this->data[$this->alias]['password1'])) {
        $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password1']);
    }       
    return true;
}

答案 2 :(得分:0)

您可以使用最新版本的cakeDC插件。此插件为您提供与登录,注销,重置密码,更改密码等相关的所有功能的所有功能。您可以找到最新版本here

答案 3 :(得分:0)

您可以简单地使用: -

Step1)

$password = $this->Auth->password($this->data['User']['password']); // It will generate the hashed password using the cakephp's Auth component.

Step2)

if($this->User->update(array('User.password'=>$password), array('User.id'=>$this->Auth->User('id')))) {
     echo $this->Session->setFlash('Password changed successfully.', 'default',   
     array('class'=>'successMsg'));
}