Bienvenidos sean a este post, en el post anterior vimos el metodo para enviar el mail al usuario pero hoy veremos al encargado de la magia.
Para comenzar debemos crear un nuevo archivo llamado cambia_clave.php en el directorio:
app/views/admin/auth
Con nuestro archivo creado le agregaremos el siguiente codigo:
cambia_clave.php
<?php include(APPDIR.'Views/layouts/header.php');?>
<div class="wrapper well">
<?php include(APPDIR.'Views/layouts/errores.php');?>
<h1>Cambia la contraseña</h1>
<form method="post">
<input type='hidden' name="token" value='<?=$token;?>'>
<div class="control-group">
<label class="control-label" for="password"> Contraseña</label>
<input class="form-control" id="password" type="password" name="password" required />
</div>
<div class="control-group">
<label class="control-label" for="password_confirm">Confirma Contraseña</label>
<input class="form-control" id="password_confirm" type="password" name="password_confirm" required />
</div>
<br>
<p class="pull-left"><button type="submit" class="btn btn-sm btn-success" name="submit">Cambia Contraseña</button></p>
<p class="pull-right"><a href="/admin/login">Ingreso</a></p>
<div class="clearfix"></div>
</form>
</div>
<?php include(APPDIR.'Views/layouts/footer.php');?>
En este caso tenemos una pagina simple donde tendremos los dos campos para ingresar la contraseña y volver a confirmar la misma, tambien volvemos a utilizar el header y el footer, asi como tambien seguimos utilizando al bootstrap, con esto tenemos la pagina que vera el usuario pero ahora veremos al verdadero gestor de todo esto, para ello debemos ir primero al archivo Usuario.php en el directorio Modelos, dentro de esta clase agregaremos el siguiente metodo:
public function get_token($token)
{
$datos = $this->db->select('id from usuarios ' .
'where token_reset = :token_reset',
[':token_reset' => $token]);
return (isset($datos[0]) ? $datos[0] : null);
}
Este metodo sera el encargado de obtener el token que almacenamos en la tabla usuarios al momento de llamar al metodo reset que nos permite cambiar la contraseña, simplemente lo obtiene y lo devuelve para que lo utilicemos en el siguiente metodo, este otro metodo estara alojado en el archivo admin.php en el directorio Controllers, dentro de esta clase agregaremos este metodo:
public function cambia_clave($token)
{
if (Sesion::get('logueado'))
Url::redireccionar('/admin');
$errores = [];
$usuario = $this->usuario->get_token($token);
if ($usuario == null)
$errores[] = "Usuario no encontrado";
if (isset($_POST['submit']))
{
$token=htmlspecialchars($_POST['token']);
$clave=htmlspecialchars($_POST['password']);
$clave2=htmlspecialchars($_POST['password_confirm']);
$usuario = $this->usuario->get_token($token);
if ($usuario == null)
$errores[] = 'Usuario no encontrado.';
if ($clave != $clave2)
{
$errores[] = 'Las claves no coinciden';
} elseif (strlen($clave) < 3) {
$errores[] = 'La clave es muy corta';
}
if (count($errores) == 0)
{
$datos = [
'token_reset' => null,
'clave' => password_hash(
$clave, PASSWORD_BCRYPT)
];
$where = [
'id' => $usuario->id,
'token_reset' => $token
];
$this->usuario->update($datos, $where);
Sesion::set('logueado', true);
Sesion::set('id_usuario', $usuario->id);
Sesion::set('exito', "Clave actualizada");
Url::redireccionar('/admin');
}
}
$titulo = "Cambiar contraseña";
$this->view->render('admin/auth/cambia_clave',
compact('titulo','token','errores'));
}
Éste metodo es el que hara la magia, para ello recibira como argumento el token enviado por el metodo reset, lo primero sera un condicional donde verifica si existe la clave logueado, en caso de ser verdadero nos redirecciona a admin, lo siguiente sera nuestro array para los errores, por el momento en blanco como siempre, luego tenemos un condicional donde verificamos si presiono el submit del formulario en reset.php, lo primero que tendremos son tres variables:
- token, recibira el token pasado desde el form
- clave, recibira la primera clave
- clave2, recibira la que sera la confirmacion de clave
Despues crearemos un objeto llamado usuario donde almacenaremos el id obtenido por medio del metodo get_token, del cual hablamos previamente, despues volveremos a tener un condicional donde verifica si el objeto anterior es igual a null, en caso de ser verdadero procede a cargar en errores el mensaje de usuario no enconrado dado que el token informado no existe en nuestra tabla usuarios, el siguiente condicional verifica si los valores en clave y clave2 son distintos, en caso de cumplirse la condicion procede a cargar en errores la notificacion de que ambas contraseñas no son iguales, y en este mismo condicional tenemos un elseif donde verifica la longitud de la primera clave informada, si este es menor a tres tambien carga en errores una notificacion indicando que la contraseña es demasiado corta.
Lo siguiente es nuestro condicional donde verificamos si errores es igual a cero, indicando que no hubo errores, aqui crearemos dos arrays:
- datos, que usaremos para borrar el token en la tabla y establecer la nueva password
- where, sera usado para el condicional del query donde pasaremos el id y el token
Despues de esto usaremos a update para actualizar nuestra tabla con los datos antes establecidos, con esto realizado procedemos a crear tres nuevas claves:
- logueado, para indicar que estamos adentro
- id_usuario, almacena el id del usuario logueado
- exito, para indicar que el cambio de contraseña fue un exito
Por ultimo nos redireccionamos de vuelta a admin, en cambio si hubo errores se omitira este condicional que acabamos de comentar y por medio de render mostramos a la pagina cambia_clave pero indicaremos cuales fueron los errores y pasaremos el token, con esto comentado veamos como quedo nuestra pagina admin.php hasta el momento:
admin.php
<?php
namespace App\Controllers;
use System\ControladorBase;
use App\Helpers\Sesion;
use App\Helpers\Url;
use App\Modelos\Usuario;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
class Admin extends ControladorBase
{
protected $usuario;
public function __construct()
{
parent::__construct();
$this->usuario = new Usuario();
}
public function index()
{
if (!Sesion::get('logueado'))
Url::redireccionar('/admin/login');
$titulo='Dashboard';
$this->view->render('admin/index',compact('titulo'));
}
public function login()
{
if (Sesion::get('logueado'))
Url::redireccionar('/admin');
$errores = [];
if (isset($_POST['submit']))
{
$user = htmlspecialchars($_POST['usuario']);
$pass = htmlspecialchars($_POST['clave']);
if (password_verify($pass,
$this->usuario->get_hash($user)) == false)
{
$errores[] = "Usuario o clave incorrectas";
}
if (count($errores) == 0)
{
$datos = $this->usuario->get_data($user);
Sesion::set('logueado',true);
Sesion::set('id_usuario',$datos->id);
Url::redireccionar('/admin');
}
}
$titulo = 'Login';
$this->view->render('admin/auth/login',
compact('titulo','errores'));
}
public function logout()
{
Sesion::eliminar();
Url::redireccionar('/admin/login');
}
public function reset()
{
if(Sesion::get('logueado'))
Url::redireccionar('/admin');
$errores = [];
if (isset($_POST['submit']))
{
$email = (isset($_POST['email']) ?
$_POST['email'] : null);
if (!filter_var($email,FILTER_VALIDATE_EMAIL))
{
$errores[]='Ingresa un email valido';
} else {
if ($email!=$this->usuario->
get_email($email))
{
$errores[]="Correo no encontrado";
}
}
if (count($errores) == 0)
{
$token=md5(uniqid(rand(),true));
$datos=['token_reset'=>$token];
$where=['email'=>$email];
$this->usuario->update($datos,$where);
$mail = new PHPMailer(true);
$mail->setFrom('noreply@tinchicus.com');
$mail->addAddress($email);
$mail->isHTML(true);
$mail->Subject="Reset a tu clave";
$mail->Body = "<p>Para cambiar tu contraseña haz click <a href='http://localhost:8000/admin/cambia_clave/$token'>en este link</a></p>";
$mail->AltBody = "Para cambiar tu contraseña ve a la siguiente direccion: http://localhost:8000/admin/cambia_clave/$token";
$mail->send();
Sesion::set('exito',"Email enviado a " .
htmlentities($email));
Url::redireccionar('/admin/reset');
}
}
$titulo = "Reseteo de cuenta";
$this->view->render('admin/auth/reset',
compact('titulo','errores'));
}
public function cambia_clave($token)
{
if (Sesion::get('logueado'))
Url::redireccionar('/admin');
$errores = [];
$usuario = $this->usuario->get_token($token);
if ($usuario == null)
$errores[] = "Usuario no encontrado";
if (isset($_POST['submit']))
{
$token=htmlspecialchars($_POST['token']);
$clave=htmlspecialchars($_POST['password']);
$clave2=htmlspecialchars($_POST['password_confirm']);
$usuario = $this->usuario->get_token($token);
if ($usuario == null)
$errores[] = 'Usuario no encontrado.';
if ($clave != $clave2)
{
$errores[] = 'Las claves no coinciden';
} elseif (strlen($clave) < 3) {
$errores[] = 'La clave es muy corta';
}
if (count($errores) == 0)
{
$datos = [
'token_reset' => null,
'clave' => password_hash(
$clave, PASSWORD_BCRYPT)
];
$where = [
'id' => $usuario->id,
'token_reset' => $token
];
$this->usuario->update($datos, $where);
Sesion::set('logueado', true);
Sesion::set('id_usuario', $usuario->id);
Sesion::set('exito', "Clave actualizada");
Url::redireccionar('/admin');
}
}
$titulo = "Cambiar contraseña";
$this->view->render('admin/auth/cambia_clave',
compact('titulo','token','errores'));
}
}
Con esto tenemos ya cubierto como enviar un correo con un link que usaremos para resetear nuestra contraseña y una pagina para el reseteo de la contraseña pero todavia nos falta un tema mas antes de probarlo pero de esto hablaremos en el proximo post.
En resumen, hoy hemos visto la pagina de cambio de contraseñas, luego hemos hablado sobre el metodo encargado del cambio en si, hemos visto como quedo hasta ahora nuestro archivo admin.php, en el proximo post lo completaremos definitivamente, espero les haya gustado sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
