2010-05-19 39 views
14

Estoy aprendiendo cakephp por mi cuenta. Traté de crear un controlador de usuario con una función de contraseña de cambio. Funciona, pero no estoy seguro de si esta es la mejor manera, y no pude buscar tutoriales útiles sobre esto. Aquí está mi código:¿Existe alguna forma mejor de cambiar la contraseña de usuario en cakephp usando Auth?

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

contraseña es la contraseña anterior, passwordn es el nuevo, password2 es el nuevo volver a teclear. ¿Hay alguna otra manera más coomon de hacerlo en el pastel?

Respuesta

29

Veo que validar y manipular datos en el controlador. Hacer esto en un modelo generalmente es una mejor práctica. Implementé una funcionalidad similar hace unos días. Mi método change_password() se ve algo como esto:

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

Y he aquí una versión simplificada de la vista utilizada con ese método:

# 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'); 

El código que hace algo interesante es en el modelo. Agregué los campos del formulario a la propiedad validate y escribí custom validation methods. Esto me permite usar los campos password1 y password2 en cualquier otro lugar de la aplicación, por ejemplo, en el formulario de registro.

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

Finalmente, en el beforeSave() de devolución de llamada del modelo puse password al hash de password1 para preparar los datos a ser almacenados en la base de datos.

+0

Niza, gracias por su respuesta, que me ayudaron a que más de la torta -me gusta. Ahora tengo un problema: no pude averiguar cómo verificar la contraseña actual en los datos con la almacenada porque no logré llamar a Auth-> contraseña ($ this-> data ['current_password']) desde el código del modelo (usuario.php). ¿Cómo hacer esto? – sipiatti

+1

Si desea leer más acerca del enfoque que presenté, se lo conoce como "modelos gordos, controladores delgados" y se puede aplicar a cualquier marco MVC. Aunque el componente Auth no está disponible desde un modelo, todo el método 'password()' hace es llamar al método hash (contraseña, nulo, verdadero); '. – Mike

+0

Gracias Mike, he aprendido mucho. Saludos! – sipiatti

21

La solución proporcionada por Mike es excelente, pero omitió la función "checkCurrentPassword". Este es un ejemplo de esa función se puede colocar en su modelo:

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

Esta solución se pone el ID de usuario actual desde el componente Auth y cambia el modelo para que apunte a ese usuario en particular. Luego compara el hash de la contraseña actual ingresada en el formulario con la contraseña hash almacenada para ese usuario.

Además, aquí es la función beforeSave puede utilizar para cifrar la nueva clave:

# 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; 
} 
0

Usted puede utilizar la última versión del plugin cakeDC. Este complemento le ofrece todas las funciones de todas las funciones relacionadas con el inicio de sesión, el cierre de sesión, restablecer la contraseña, cambiar la contraseña, etc. Puede encontrar la última versión here.

0

Usted puede simplemente usar el: -

Paso 1)

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

Paso 2)

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