Restablecer contraseña mediante correo electrónico con PHP y MySQL

En esta ocasión vamos a crear un script que nos permita restablecer la contraseña de usuarios mediante correo electrónico.

Para este ejercicio vamos a trabajar con la siguiente base de datos:

--
-- Estructura de tabla para la tabla `users`
--
CREATE TABLE IF NOT EXISTS `tblreseteopass` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`idusuario` int(10) unsigned NOT NULL,
`username` varchar(15) NOT NULL,
`token` varchar(64) NOT NULL,
`creado` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idusuario` (`idusuario`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

--
-- Estructura de tabla para la tabla `users`
--

CREATE TABLE IF NOT EXISTS `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`nombre` varchar(60) NOT NULL,
`username` varchar(15) NOT NULL,
`password` varchar(64) NOT NULL,
`email` varchar(70) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Y generaremos los siguientes archivos:

  • index.html – Formulario para solicitar el cambio de contraseña mediante el correo electrónico.
  • validaremail.php – Script que valida y envía por correo electrónico el link para resetear la contraseña.
  • restablecer.php – Script que valida el token y muestra al usuario el formulario para resetear la contraseña.
  • cambiarpassword.php – Script que actualiza la información de la contraseña en la base de datos.

 

Archivo: index.html

Lo primero que vamos a hacer es generar el formulario donde pida el correo electrónico de la cuenta que se desea restablecer. El cual solo va a contener un input de tipo text para que el usuario escriba su correo. Adicional a esto vamos a crear un div con el atributo id=”mensaje” dentro del cual mostraremos una leyenda que le indique al usuario que el correo para restablecer su contraseña fue enviado.

    <form id="frmRestablecer" action="validaremail.php" method="post">
      <div class="panel panel-default">
        <div class="panel-heading"> Restaurar contraseña </div>
        <div class="panel-body">
          <div class="form-group">
            <label for="email"> Escribe el email asociado a tu cuenta para recuperar tu contraseña </label>
            <input type="email" id="email" class="form-control" name="email" required>
          </div>
          <div class="form-group">
            <input type="submit" class="btn btn-primary" value="Recuperar contraseña" >
          </div>
        </div>
      </div>
    </form>

    <div id="mensaje"></div>

Para enviar el formulario vamos a utilizar ajax de jquery, y lo hacemos de la siguiente forma: capturamos el evento submit del formulario y evitamos que lo envie con event.preventDefault(), en su lugar serializamos el formulario y lo enviamos por ajax al script validaremail.php

    <script>
      $(document).ready(function(){
        $("#frmRestablecer").submit(function(event){
          event.preventDefault();
          $.ajax({
            url:'validaremail.php',
            type:'post',
            dataType:'json',
            data:$("#frmRestablecer").serializeArray()
          }).done(function(respuesta){
            $("#mensaje").html(respuesta.mensaje);
            $("#email").val('');
          });
        });
      });
    </script>

Archivo: validaremail.php

En el archivo validaremail.php definimos 2 funciones, una que nos genere el link para la descarga del archivo y otra para que envíe el correo electrónico.

function generarLinkTemporal($idusuario, $username){
   // Se genera una cadena para validar el cambio de contraseña
   $cadena = $idusuario.$username.rand(1,9999999).date('Y-m-d');
   $token = sha1($cadena);

   $conexion = new mysqli('localhost', 'root', '', 'ejemplobd');
   // Se inserta el registro en la tabla tblreseteopass
   $sql = "INSERT INTO tblreseteopass (idusuario, username, token, creado) VALUES($idusuario,'$username','$token',NOW());";
   $resultado = $conexion->query($sql);
   if($resultado){
      // Se devuelve el link que se enviara al usuario
      $enlace = $_SERVER["SERVER_NAME"].'/pass/restablecer.php?idusuario='.sha1($idusuario).'&token='.$token;
      return $enlace;
   }
   else
      return FALSE;
}

function enviarEmail( $email, $link ){
   $mensaje = '<html>
     <head>
        <title>Restablece tu contraseña</title>
     </head>
     <body>
       <p>Hemos recibido una petición para restablecer la contraseña de tu cuenta.</p>
       <p>Si hiciste esta petición, haz clic en el siguiente enlace, si no hiciste esta petición puedes ignorar este correo.</p>
       <p>
         <strong>Enlace para restablecer tu contraseña</strong><br>
         <a href="'.$link.'"> Restablecer contraseña </a>
       </p>
     </body>
    </html>';

   $cabeceras = 'MIME-Version: 1.0' . "\r\n";
   $cabeceras .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
   $cabeceras .= 'From: Codedrinks <mimail@codedrinks.com>' . "\r\n";
   // Se envia el correo al usuario
   mail($email, "Recuperar contraseña", $mensaje, $cabeceras);
}

Ya que hemos definido las dos funciones que vamos a utilizar continuamos con el código que valida el correo electrónico, verificamos que no este vacío y hacemos una consulta a la base de datos para verificar si el correo existe. En caso de que nos devuelva algún registro llamamos a la función generarLinkTemporal la cual nos devolverá el link  para que el usuario pueda resetear la contraseña, el cual pasaremos a la función enviarEmail para que envíe la información al correo del usuario. Al final devolvemos una respuesta mediante json

$email = $_POST['email'];

$respuesta = new stdClass();

if( $email != "" ){
   $conexion = new mysqli('localhost', 'root', '', 'ejemplobd');
   $sql = " SELECT * FROM users WHERE email = '$email' ";
   $resultado = $conexion->query($sql);
   if($resultado->num_rows > 0){
      $usuario = $resultado->fetch_assoc();
      $linkTemporal = generarLinkTemporal( $usuario['id'], $usuario['username'] );
      if($linkTemporal){
        enviarEmail( $email, $linkTemporal );
        $respuesta->mensaje = '<div class="alert alert-info"> Un correo ha sido enviado a su cuenta de email con las instrucciones para restablecer la contraseña </div>';
      }
   }
   else
      $respuesta->mensaje = '<div class="alert alert-warning"> No existe una cuenta asociada a ese correo. </div>';
}
else
   $respuesta->mensaje= "Debes introducir el email de la cuenta";
 echo json_encode( $respuesta );

Archivo: restablecer.php

El archivo restablecer.php se encarga de verificar que el link para cambiar la contraseña sea correcto, por lo tanto lo primero que hacemos es obtener por GET el token y el idusuario para después verificar que se encuentre en la tabla tblreseteopass. De ser así se muestra el formulario para cambiar la contraseña en caso contrario se redirecciona hacia la pagina index.html

<?php
$token = $_GET['token'];
$idusuario = $_GET['idusuario'];

$conexion = new mysqli('localhost', 'root', '', 'ejemplobd');

$sql = "SELECT * FROM tblreseteopass WHERE token = '$token'";
$resultado = $conexion->query($sql);

if( $resultado->num_rows > 0 ){
   $usuario = $resultado->fetch_assoc();
   if( sha1($usuario['idusuario']) == $idusuario ){
?>
<!DOCTYPE html>
<html lang="es">
 <head>
  <meta name="author" content="denker">
  <title> Restablecer contraseña </title>
  <link href="css/bootstrap.min.css" rel="stylesheet">
  <link href="css/bootstrap-theme.min.css" rel="stylesheet">
  <link href="css/style.css" rel="stylesheet">
 </head>

 <body>
  <div class="container" role="main">
   <div class="col-md-4"></div>
   <div class="col-md-4">
    <form action="cambiarpassword.php" method="post">
     <div class="panel panel-default">
      <div class="panel-heading"> Restaurar contraseña </div>
      <div class="panel-body">
       <p></p>
       <div class="form-group">
        <label for="password"> Nueva contraseña </label>
        < input type="password" class="form-control" name="password1" required>
       </div>
       <div class="form-group">
        <label for="password2"> Confirmar contraseña </label>
        <input type="password" class="form-control" name="password2" required>
       </div>
       <input type="hidden" name="token" value="<?php echo $token ?>">
       <input type="hidden" name="idusuario" value="<?php echo $idusuario ?>">
       <div class="form-group">
        <input type="submit" class="btn btn-primary" value="Recuperar contraseña" >
       </div>
      </div>
     </div>
    </form>
   </div>
  <div class="col-md-4"></div>
  </div> <!-- /container -->

  <script src="js/jquery-1.11.1.js"></script>
  <script src="js/bootstrap.min.js"></script>
 </body>
</html>
<?php
   }
   else{
     header('Location:index.html');
   }
 }
 else{
     header('Location:index.html');
 }
?>

Archivo: cambiarpassword.php

El archivo cambiarpassword.php se encarga de recibir las contraseñas, el idusuario y el token para actualizar la información en la base de datos, por lo tanto primero se verifica que se hayan recibido todos los datos posteriormente se realiza una consulta para verificar si el token existe, que las contraseñas coincidan y posteriormente se actualiza la tabla users con la nueva contraseña, al final se elimina el registro de la tabla: tblreseteopass.


<?php
$password1 = $_POST['password1'];
$password2 = $_POST['password2'];
$idusuario = $_POST['idusuario'];
$token = $_POST['token'];

if( $password1 != "" && $password2 != "" && $idusuario != "" && $token != "" ){
?>
<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title> Restablecer contraseña </title>
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <link href="css/bootstrap-theme.min.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">
  </head>

  <body>
    <div class="container" role="main">
      <div class="col-md-2"></div>
      <div class="col-md-8">
<?php
   $conexion = new mysqli('localhost', 'root', '', 'ejemplobd');
   $sql = " SELECT * FROM tblreseteopass WHERE token = '$token' ";
   $resultado = $conexion->query($sql);
   if( $resultado->num_rows > 0 ){
      $usuario = $resultado->fetch_assoc();
      if( sha1( $usuario['idusuario'] === $idusuario ) ){
         if( $password1 === $password2 ){
            $sql = "UPDATE users SET password = '".sha1($password1)."' WHERE id = ".$usuario['idusuario'];
            $resultado = $conexion->query($sql);
            if($resultado){
               $sql = "DELETE FROM tblreseteopass WHERE token = '$token';";
               $resultado = $conexion->query( $sql );
?>
               <p class="alert alert-info"> La contraseña se actualizó con exito. </p>
<?php
            }
            else{
?>
              <p class="alert alert-danger"> Ocurrió un error al actualizar la contraseña, intentalo más tarde </p>
<?php
            }
         }
         else{
?>
           <p class="alert alert-danger"> Las contraseñas no coinciden </p>
<?php
         }
      }
      else{
?>
        <p class="alert alert-danger"> El token no es válido </p>
<?php
      }
   }
   else{
?>
      <p class="alert alert-danger"> El token no es válido </p>
<?php
   }
?>
</div>
<div class="col-md-2"></div>
</div> <!-- /container -->
<script src="js/jquery-1.11.1.js"></script>
<script src="js/bootstrap.min.js"></script>
</body>
</html>
<?php
}
else{
   header('Location:index.html');
}
?>

Para que el link tenga fecha de caducidad podemos agregar un evento de MySQL que cada determinado tiempo elimine los registros que han caducado. Supongamos que cada 12 horas queremos que se ejecute el código que elimina los registros que fueron creados hace mas de dos días el evento quedaría de la siguiente forma:

CREATE EVENT mievento
   ON SCHEDULE EVERY 12 HOUR
      CURRENT_TIMESTAMP
   DO
      DELETE FROM tblreseteopass WHERE creado <= DATE_SUB(CURTIME(), INTERVAL 2 DAY)

Eso es todo, pueden moverle al código para agregar una mayor funcionalidad, Aquí les dejo el link de descarga.

download

74 comentarios en “Restablecer contraseña mediante correo electrónico con PHP y MySQL”

  1. Douglas Uriel dice:

    hola amigo al momento de cambiar el pass me da este error:

    Warning: mysqli::query(): Empty query in C:\xampp\htdocs\pass\cambiarpassword.php on line 31
    El token no es válido

    1. denker dice:

      Hola amigo, solo cambia el nombre de la variable $consulta por $sql en la linea 30 del archivo cambiar password

      1. José Rodríguez dice:

        Hola Denker me puedes pasar un mail personal, tengo una página q necesito añadir algunas trabajos extras Como ejemplo recuperar la contraseña de usuarios y otras cosas más. Gracias por adelantado.

  2. Douglas Uriel dice:

    si exacto funciono a la perfección gracias por el aporte y mi pregunta es si tienes un ejemplo o de como hacer esto . y que le llegue a su corre

    Estimado: nombre del usuario
    Su Token para Verificar su cuenta es: Kpyl02x7sj5
    Fecha de Caducidad: 2014-08-1 10:11:51

    como lo puedo hacer o puedes hacer un ejemplo de como hacer esto .. saludos cordiales

    1. denker dice:

      Eso lo puedes hacer en el archivo validaremail.php, tienes que hacer una consulta para recuperar el nombre de usuario y pasarselo a la funcion enviaremail, que es donde le das el formato al mensaje que recibirá el usuario.

  3. ZoomWolf dice:

    Excelente aporte, es de mucha utilidad el ejemplo, la verad que tu pagina es maravillosa.

  4. Mafe Díaz dice:

    Hola, mira yo lo hice todo tal y como está ahí pero no me llega ningún correo para el restablecimiento donde puede estar el error.
    Gracias

    1. denker dice:

      Hola Mafe, lo estas probando en local?, necesitas configurar tu servidor de correo.

      1. Mafe Díaz dice:

        Hola estoy trabajando desde local, y descargue el Post Cast Server para configurar pero igual no me da, tu no sabes como podría configurarlo
        Gracias

      2. Rudy Adalid Osorio Sosa dice:

        Hola Denker… Me pasa que cree la tabla `tblreseteopass` y me funciona, la otra tabla no porque ya tengo la tabla con esos campos pero….. Al enviar mi solicitud de restablecer contraseña, me da el mensaje que se ha enviado pero no me llega nada al correo…. no lo hice en local, lo hice en mi servidor pero tambien mi pagina esta por ip… no por un nobre de domino… cual crees que puede ser el problema.? De antemano muchas gracias… Todo muy profesional aqui y gracias por compartir tu codigo… A mi me gustaria ayudar aqui y se que de repente aportare algo, poco o mucho porque me ha servido de mucho tu codigo… eres genial…

    2. Juanfer dice:

      Hola, esto lo pudiste arreglar? Me pasa lo mismo.

  5. PAblo dice:

    Antes de nada muchas gracias por el aporte, se agradece!

    Mi problema viene al confirmar el enlace desde al clicar en el enlace enviado al email para restablecer la contraseña, da este error.

    Not Found

    The requested URL /pass/restablecer.php?idusuario=97e3d7dde9cfe479809108e9e82145a7912a08a2&token=c36e3fbb140fa941e9142619f0b9e3e66ae79a41 was not found on this server.

    No consigo averiguar porque.

    Gracias de nuevo! Un saludo.

    1. denker dice:

      A la URL le falta el nombre del servidor, si estas trabajando en local seria http://localchost/pass/restablecer.php?idusuario=97e3d7dde9cfe479809108e9e82145a7912a08a2&token=c36e3fbb140fa941e9142619f0b9e3e66ae79a41

      1. Pablo dice:

        Muchas gracias! 🙂

        Si no es mucha molestia, lo último que ocurre es que pinta en el campo “password” el token tal cual y no la nueva password.

        un saludo.

      2. Pablo dice:

        Gracias Denker!

        Ya todo es correcto excepto que en la base de datos se pinta en el campo “password” el “token” y no el nuevo password.

        Saludos!

        1. Juanfer dice:

          Pablo, tu conseguiste hacer que en el campo de clave, te guarde la nueva clave en lugar del token?

      3. gbariel dice:

        Hola.. una ayuda cuando coloco las dos contraseñas me arroja token no valido porque sucede esto? que debo arreglar?

      4. alex dice:

        Hola buenas viejo una consulta, estoy tratando de implementar el codigo para un proyecto. Importe la base de datos y no me da error en validaremail.php. El hecho es que cuando introduzco cualquier email me dice que no existe una cuenta asociada a este correo, no logro ver el error, introduce valores ya en la base de datos y nada

      5. Steven dice:

        Hola, primero que todo Gracias por el aporte me ha sido muy util, aunque luego de clickear para la recuperación de contraseña me envía el correo pero sin el link para su restauración, me podrían colaborar con ello?

      6. Otoniel Palaco dice:

        en el link del correo me sale esto y no logro solucionar colocó bien el dominio y me sigue saliendo esto…

        The requested URL /pass/restablecer.php was not found on this server.

        Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

  6. pablo dice:

    Hola Denker,

    ¿Sabrías decirme porque no consigo que se pinte la nueva password en la bbdd y sin embargo se pinta el token en su lugar?

    Muchas gracias.

  7. Daniel dice:

    Hola:

    Todo luce genial, pero cuando presiono el botón de recuperar contraseña del index.html no sucede nada, incluso con los archivos sin modificar. ¿Sabes a qué puede deberse?

    ¡Gracias!

    1. Roberto dice:

      ¿Esto lo pudiste resolver? Me pasa exactamente lo mismo, y veo en más comentarios que no somos los únicos

    2. Rudy Adalid Osorio Sosa dice:

      Bien… Yo note que cuando ingreso el correo y le doy clic y es la primera vez, este me tira el resultado de que ya se envio el enlace para restablecer contraseña. Si lo hago una segunda vez ya no lo permite porque creo que ya existe en esa tabla la espera de restablecer el password…. Yo lo borre de la tabla ese dato y luego intente y me salio otra vez que revisara mi correo… Por eso no aparece nada, porque al intentarlo la primera vez ya se envio.. al restablecerlo, ese dato se borra.

  8. Juanfer dice:

    Está muy bien, pero particularmente a mi no me llega el correo, veo que en mi bs si se guarda el tokemn, pero no me llega el correo, he probado escribiendo diferetes cuentas.

    1. Antonio dice:

      Hola juanfer, en vez de recibir la contraseña en mi email simplemente se guarda el token en la tabla tblreseteopass… TIenes una version mas actualizada? sería muy útil para mi proyecto. Gracias

  9. Juanfer dice:

    En restablecer.php tienens mal la ínea 29:

    El formaulario se llama “cambiarpassword.php”, no “cambiarclave.php”

    😉

  10. Juanfer dice:

    Ya solucioné todo lo anterior, sinembargo veo que en lugar de la nueva clave, me guarda el token….

    1. maikel carreño dice:

      hola juanfer espero q por favor me ayude me pasa los mismo que te pasaba he igual estoy trabajando local no me llega la clave al correo como lograste solucionarlo.

    2. Roxy dice:

      Juanfer necesito me ayudes o me expliques como lo haciste funcionar

  11. Pablo dice:

    Juanfer, me pasa igual, no logré solucionarlo.

    1. Juanfer dice:

      Tomen estos tres consejos para que les funcione:

      1) En el archivo cambiarpassword.php, en la línea 33 deben quitarle el .sha1. Con esto guararán la clave, en lugar del token.

      $sql = “UPDATE users SET password = ‘”.sha1($password1).”‘ WHERE id = “.$usuario[‘idusuario’];

      2) En restablecer.php tienens mal la ínea 29:

      El formaulario se llama “cambiarpassword.php”, no “cambiarclave.php”

      3) Si no están recibiendo el correo, con esto ya que todo está bien, darse cuenta si el servidor de su hosting no está en una lista negra de mailing. En mi caso me tocó desnudar los correos que si me empezaron a llegar, a correos gmail, porque a servidores hotmail u outlook no llegaban, debido a que Godaddy (en este caso) tenía una ip de servidor de correo bloqueado por hotmail/outlook. Cómo lo solucioné? Cambiándome a iPage (el cual uso siempre, pero este proyecto lo tenia en godaddy).

      4) http o https?: Algo en lo que me ayudaron en un foro muy útil. Resulta que a correos gmail llegaba el link normal, pero a outlook, cuando empezaron a llegar, me llegaban como https y me “jodían” el link. Lo solucioné así:

      en validaremail.php línea 12:

      El código luce así:

      $enlace = $_SERVER[“SERVER_NAME”].’/pass/restablecer.php?idusuario=’.sha1($idusuario).’&token=’.$token;

      Solo deben agregarle “http://”

      $enlace = ‘http://’. $_SERVER[“SERVER_NAME”].’/pass/restablecer.php?idusuario=’.sha1($idusuario).’&token=’.$token;

      Agregando esto, llega el link normal (http) a todos los correos.

      Eso es todo amigos. Les pido el favor que si encuentran la solución a lo que aparece al final del post, lo de crear un evento a MYSQL para ponerle caducidad al token, me lo hagan saber, pues no lo he solucionado y me gustaría darle fecha de caducidad.

      CREATE EVENT mievento
      ON SCHEDULE EVERY 12 HOUR
      CURRENT_TIMESTAMP
      DO
      DELETE FROM tblreseteopass WHERE creado <= DATE_SUB(CURTIME(), INTERVAL 2 DAY)

      Gracias. Me cuentan si les funcionó.

      1. sun2012 dice:

        hola, desde el phpmyadmin de tu hosting en en sql puedes copiar el codigo del evento, y si no pues desde la funcion query se lo pasas como una cade y ya saludos.

      2. gbariel dice:

        Amigo me arroja token no valido.. porque me arroja ese mensaje?

  12. Monica dice:

    A mi al igual que Juan fernando me sucede que Está muy bien, pero no me llega el correo, veo que en mi bs si se guarda el tokemn, pero no me llega el correo, he probado escribiendo diferetes cuentas.

  13. Monica dice:

    Espero alguien me pueda responder y de antemando muchas gracias!!!

  14. Buen dia,

    El codigo que esta inmediatamente debajo de la parte que dice “Ya que hemos definido las dos funciones que vamos a utilizar continuamos con el código que valida el correo electrónico…” No entiendo en que archivo colocarlo, no se si estoy leyendo mal o que pero no logro saber donde colocarlo, y como empieza con el numero 1 no se si ponerlo en un archivo distinto, alguien podra ayudarme?

    Saludos

  15. Andres dice:

    Hola amigo. cuando actualizo la clave me dice token no valido lo tengo en mi servidor pago. me podrias ayudar porfavor, gracias de antemano

  16. Rolando Segovia dice:

    Excelente tutorial, el codigo me funciono (aunque tuve que adecuarlo a lo mio), sin embargo hay algunos detalles que no logro comprender bien, uno de ellos es que no me funciona el script en el que se utiliza el AJAX (lo tuve que comentar), agradeceria una explicacion, al igual que la parte del JSON, ya que me muestra un mensaje no muy profesional en su presentacion (como se utiliza?).

    Por lo demas lo he puesto a produccion, quedando cada dia mejorarlo sobre todo la parte donde elimino el token…bueno gracias por el aporte y a seguir trabajando.

  17. DUILIO dice:

    Este codigo esta muy bueno.. ya muchos compañeros como DENKER y juanfer nos han ayudado bastante, el primero facilitandonos todo el codigo que es de su propiedad, y el segundo ayudandonos con soluciones a pequeñisimos errores de nuesto amigo denker.

    lo ideal seria que este codigo no se pierda, con esto quiero decir, que ahora que ya tenemos funcionando este codigo para implementarlo en nuestras web. hay que añadirle mas funciones para que sea un codigo de primer nivel.

    1. como por ejemplo que cuando enviemos un correo de restauracion lo haga mandando un codigo aleatorio para evitarnos el robo de cuentas.

    2. Que al enviar un email para cambiar el password tenga un tiempo de vida (por ejemplo 2 horas, 8 horas, etc.)

    3. al momento de que nos llegue el email tenga una bonita presentacion y no simple texto para indicarnos el link de cambio de password.

    4. que nuestro nuevo password tenga 128 o 256 caracteres junto con un salt para tener doble proteccion, ya que para romper los 128 caracteres de password seria mas dificl y encima que coincida con el salt tambien de 128 caracteres seria genial.

    5. Otras implementaciones adicionales que se pueda.

    Estas son ideas que podemos realizar si todos nos ayudamos y alli podemos reutilizar este codigo muchas veces todo con apoyo de nosotros mismos.

    1. Veo que planteas algunas cosas que ya están dentro del código.

      “1. como por ejemplo que cuando enviemos un correo de restauracion lo haga mandando un codigo aleatorio para evitarnos el robo de cuentas.”

      Por lo que vi, ya posee un código aleatorio añadido mediante la función rand(1,999999) dentro del mismo token.

      “2. Que al enviar un email para cambiar el password tenga un tiempo de vida (por ejemplo 2 horas, 8 horas, etc.)”

      Eso se produce gracias al evento SQL, también explicado en el post.

      “3. al momento de que nos llegue el email tenga una bonita presentacion y no simple texto para indicarnos el link de cambio de password.”

      Eso en ocasiones dependerá de qué modo de recepción de correo tenga definido el usuario en su cliente de correo. Si no tiene habilitada la vista HTML, los arreglos estéticos podrían perjudicar la finalidad del mail que es que el usuario tenga acceso al cambio de su clave.

      “4. que nuestro nuevo password tenga 128 o 256 caracteres junto con un salt para tener doble proteccion, ya que para romper los 128 caracteres de password seria mas dificl y encima que coincida con el salt tambien de 128 caracteres seria genial.”

      Cualquier cambio que amplíe la seguridad es útil.
      Un modo que se me ocurre sería hashear el token mediante password_hash(), y leyendo luego su contenido con password_verify().
      Info para password_hash(): http://php.net/manual/es/function.password-hash.php
      Info para password_verify(): http://php.net/manual/es/function.password-verify.php

      Coincido en que la ayuda entre todos es el mejor fundamento para la continuidad del software libre.

  18. Rolando Segovia dice:

    Buena idea lo de DUILIO, son buenas características que se pueden ir implementando, todo ponemos un “granito de arena” en mejorar el código, para que nuestra comunidad de desarrolladores luego pueda aprovechar dichas mejoras y compartir con el “mundo”, como dijo alguien “de la unión nace la fuerza”

  19. cris dice:

    Hola, todo perfecto, excepto que al recuperar contraseña te dice que se ha enviado un correo al registrado, pero no llega. No se si el servidor de correos tiene que ser en un hosting de pago, yo lo tengo en hostinger pero gratuito. Que puede ser?, gracias

  20. Dero dice:

    Hola primeramente gracias por el código!! pero tengo una duda, no me manda el correo pero lei en los comentarios que hay que configurar el servidor de correo como hago eso? que herramienta ocupo para realizar eso? de antemano muchas gracias

  21. maikel carreño dice:

    hola compañeros a mi no me llega el correo, en mi bd si se guarda el tokemn, pero no me llega el correo, lo estoy realizando local con postcast server. Espero de su ayuda.

  22. fabian dice:

    me dice que falta un archivo login.php ……. he cerado un login.php

    pero me sigue sin funcionar

  23. Juan dice:

    si el usuario pide otra contraseña ? no daría error por el unique key ? UNIQUE KEY `idusuario` (`idusuario`)
    se debería hacer una excepción si eso pasa que haga un update a la tabla tblreseteopass o simplemente enviarle un mensaje diciéndole que ya fue enviando un correo con su link para generar una nueva contraseña que espera x tiempo si desea pedir otro
    una simple sugerencia ! gracias por el código me ayudo bastante a implementar algo parecido
    dándole un token a los usuarios para activar

  24. alberto dice:

    Con el error que menciona Juan sobre pedir otro correo con el token se soluciona agregando una consulta antes de llamar la funcion de generarlink en la cual valide el ID obtenido de la consulta del correo contra la tabla de reseteopass y si esta contiene el ID solo mande un mensaje por medio de javascipt,

  25. alberto dice:

    Para los que tienen el problema con email que no es recibido tengan en cuenta que su hosting ya sea de pago o free, les ofresca servicio de correo para su pagina, y para los que utilicen el codigo en local les recomiendo linux como yo lo estoy haciendo sobre archlinux , con Apache, Php y Mariadb como servicio de correo uso postfix el cual se puede configurar para que use tu cuenta de gmail para enviar los correos generados por medio de PHP y solo es cuestion de configurar la ruta en php.ini y en postfix agregar el servidor smtp de google con tu cuenta y password.

  26. edgar lozano dice:

    alguien me puede pasar el código funcionando con el sql, he hecho las recomendaciones pero no me da por ningún lado gracias

  27. alberto dice:

    El evento para borrar los token generado lo puse de la siguiente manera
    CREATE EVENT
    tokendelete
    ON SCHEDULE EVERY 12 HOUR
    STARTS CURRENT_TIMESTAMP
    DO
    DELETE FROM tblreseteopass WHERE creado <= DATE_SUB(CURTIME(), INTERVAL 1 DAY);

    como venia en el ejemplo me marco error en la sentencia CURRENT_TIMESTAMP, pero anteponiendo STARTS ya no me marco error

    Al final logre colocar todo el codigo en 2 archivos colocando todas las consultas de PHP y validaciones con ayuda de
    if(isset($_POST['submit']))

    Muchas Gracias a todos pos su ayuda. y sobre todo al creador de este codigo.

  28. Harvey dice:

    Muy buen aporte

  29. Hola! excelente aporte para ampliar mis conocimientos 🙂

    tengo una duda, en la base de datos que actualmente uso, los usuarios están registrados en la tabla “usuarios” y el nombre del usuario en el campo “login”, qué campos debería corregir en este script para que no haya problema con ello?

    1. Parece que logré resolverlo, solo no llegan los mails con el mensaje, en qué parte de este script puedo modificar el mail desde el que se envía este mensaje?

    2. si lo subo a mi sitio web no me trabaja, solo en localhost: http://howller.com/recuperar.php

    3. Voy perfecto! al parecer ya funciona todo, a excepción del último paso: al introducir la nueva contraseña me da el mensaje de error: Ocurrió un error al actualizar la contraseñaa, intentalo más tarde

    4. Funciona a la perfección! olvide cambiar el nombre de la tabla de usuarios en una sección, gracias por el aporte 😀

      1. linohu dice:

        ¿un favor en que parte de la seccion olvidaste cambiar, te refieres?

  30. linohu dice:

    tambien quiero felicitar al creador de este codigo, en mi caso llegue hasta donde me llega un correo a mi buzon y hago clic en el hiperviculo donde me presenta una ventana con Restaurar contraseña -Nueva contraseña-Confirmar contraseña al final me muestra la ventana que indica (La contraseña se actualizó con exito) y cuando intento ingresar al formulario de ingreso de usuarios ahy el error comienza usuario y contraseña incorrectos, he estado viendo la tabla de usuarios si llega a modificar la contraseña en el campo pasword pero llega cifrada a ese campo con 40 caracteres pero he estado investigando que no deben ser 40 caracteres sino una contraseña cifrada es de 32 caracteres, solicito me apoyen con este problemita que estoy pasando: el formulario de registro es http://participa.pe.hu/ y el formulario de recuperacion de recuperacion de contraseña es http://participa.pe.hu/recupera_pass/ agradezco la ayuda de antemano

    1. gabriel dice:

      Amigo me podrías ayudar con el código.. al momento de cambiar el pass me arroja token no valido.. podrias ayudarme?

      1. linohu dice:

        Hola amigo, solo cambia el nombre de la variable $consulta por $sql en la linea 30 del archivo cambiar password

  31. Israel Duran dice:

    Gracias, no me imaginaba como implementar la función de restablecer contraseña en mi sitio, ya lo implementé y me quedó muy bien. Seguiré aprendiendo sin duda codedrinks será de las páginas que visitaré a menudo.

  32. gbariel dice:

    Cuando coloco las 2 contraseñas nuevas y le indico restablecer contraseña me envia al cambiarpassword.php pero me arroja el mensaje de El token no es valido, en este caso porque me aparece ese mensaje?

  33. roxy dice:

    hola necesito ayuda en el index digito mi correo y de esa pantalla no me pasa anada simplemete borra el text alguien sabe porque ? ayuda pliss

    1. marianosanchez2016 dice:

      Me pasa lo mismo ….

  34. ana dice:

    hola me sale el siguiente error cuando hago click desde el correo para recuperar la clave No se encontró la dirección DNS del servidor de restablecer.php.

  35. sergio dice:

    HOLA!!! denker!!!…todo funciona increible…solo tengo el problemilla de que el mensaje no se muestra en el div, sino que me pasa a una pagina en blanco con el mensaje, como puedo solucionarlo ?

    1. Sergio dice:

      Ya ya quedo…resulta que se pone SIEMPRE antes el link de JQUERY y enseguida el script que vas a correr…todo el jquery debe ir antes del cierre de body…era el problema…

  36. Steven dice:

    Excelente aporte, aunque se me ha complicado mucho hacerlo en Modelo – Vista – Controlador… creo que necesitaré ayuda para elllo.

  37. Jigal dice:

    a los que les apareció el error de token no valido había un error en la sentencia de cambiarpassword.php mas especificamente en la linea 30
    $sql = “SELECT * FROM tblreseteopass WHERE token = ‘$token'”;
    $resultado = $conexion->query($consulta); –> Cambien a $resultado = $conexion->query($sql);

    eso es todo, respecto al email que tampoco llegaba si efectivamente hay una lista en outlook.com y hotmail.com a los hosting de goddady.
    Saludos

  38. Miguel Alejandro Velazquez Lizalde dice:

    Hola amigo
    Me gustaría saber si existe alguna forma de recuperar las funciones ( javascript, html,y otras.)
    de mi teléfono sin necesidad de conectarme a una pc ya que no puedo stablecer coneccion por wi fi o datos pues nisiquiera me da acceso a la configuración del dispositivo móvil .

  39. carlos dice:

    tengo la misma inquietud de muchos abro el index digito el email luego presiono el boton de recuperar contraseña y no sucede absolutamente nada

    1. sun2012 dice:

      para localhost necesitas instalar un servidor de correos local o usar una librería que soporte envió de correos por smtp como gmail.

Deja un comentario