sql >> Base de Datos >  >> RDS >> Mysql

Sistema de restablecimiento de contraseña en PHP

Una característica muy importante de cualquier buen sitio web de membresía es un sistema de restablecimiento de contraseña porque algunos usuarios están obligados a olvidar su contraseña. En este tutorial, describo los pasos necesarios para recuperar la contraseña de un usuario; también implementaremos dicho sistema usando PHP y una base de datos MySQL en este tutorial.

Todo el proceso de implementación de dicho sistema se puede dividir en 3 pasos principales. Para facilitar la explicación, analicemos estos pasos en términos de los formularios que presentaremos para que el usuario complete:

  1. Formulario de inicio de sesión:  Este formulario toma la combinación de nombre de usuario y contraseña de un usuario e inicia sesión si está registrado en el sistema. En este formulario proporcionamos un "¿Olvidó su contraseña?" enlace en caso de que el usuario haya olvidado su contraseña y necesite restablecerla.
  2. Formulario de correo electrónico:  Si el usuario ha olvidado su contraseña, puede hacer clic en el enlace "¿Olvidó su contraseña?" enlace en la página de inicio de sesión para restablecerlo. Al hacer clic en este enlace, los llevará a otra página que les pedirá que ingresen el correo electrónico. Cuando la dirección de correo electrónico que proporcionan no está en nuestra tabla de usuarios en la base de datos, mostraremos un mensaje de error que dice "No existe tal usuario en nuestro sistema". Si, por otro lado, el usuario existe, generaremos un token único (una cadena aleatoria única) y almacenaremos este token junto con esa dirección de correo electrónico en la tabla password_resets en la base de datos. Luego les enviaremos un correo electrónico que tenga ese token en un enlace. Cuando hacen clic en el enlace del correo electrónico que les enviamos, se les enviará de vuelta a nuestro sitio web en una página que les presenta otro formulario.
  3. Formulario de nueva contraseña:  Una vez que el usuario regrese a nuestro sitio web, tomaremos el token que proviene del enlace y lo almacenaremos en una variable de sesión. Luego les presentaremos un formulario que les pide que ingresen una nueva contraseña para su cuenta en nuestro sitio web. Cuando se envíe la nueva contraseña, consultaremos la tabla password_resets para el registro que tiene ese token que acaba de llegar del enlace en el correo. Si el token se encuentra en la tabla password_resets, estamos seguros de que el usuario es quien es y que hizo clic en el enlace de su correo. En este punto, tomamos el correo electrónico del usuario de la tabla password_resets (recuerde que habíamos guardado el token junto con su dirección de correo electrónico) y usamos ese correo electrónico para buscar al usuario de la tabla de usuarios y actualizar su contraseña.

Espero que sea lo suficientemente claro. Si no es así, quédese y quedará más claro a medida que implementemos.

Implementación

Cree una base de datos llamada password_recovery y en esa base de datos, cree dos tablas, a saber, usuarios y password_resets con los siguientes campos:

usuarios:

+----+-----------+--------------+------------+
|     field      |     type     | specs      |
+----+-----------+--------------+------------+
|  id            | INT(11)      |            |
|  username      | VARCHAR(255) |            |
|  email         | VARCHAR(255) | UNIQUE     |
|  password      | VARCHAR(255) |            |
+----------------+--------------+------------+

restablecimiento_de_contraseña:

+----+-----------+--------------+------------+
|     field      |     type     | specs      |
+----+-----------+--------------+------------+
|  id            | INT(11)      |            |
|  email         | VARCHAR(255) |            |
|  token         | VARCHAR(255) | UNIQUE     |
+----------------+--------------+------------+

Nota: Esta aplicación requiere que el usuario ya esté registrado en el sistema. Pero no cubriremos la parte de registro de usuarios en este tutorial porque ya se ha cubierto en este sitio. Puede seguir ese tutorial primero (le recomiendo que lo haga) o no, pero tenga en cuenta que necesitamos tener un usuario en nuestra tabla de usuarios en la base de datos antes de que podamos proceder a restablecer su contraseña. Entonces, de una forma u otra, agregue un usuario a su base de datos mysql. Puede utilizar una herramienta como PHPMyAdmin y asegurarse de cifrar la contraseña mediante md5().

Ahora cree una carpeta de proyecto llamada recuperación de contraseña y asegúrese de que esta carpeta esté en el directorio de su servidor (carpeta htdocs o carpeta www). En esa carpeta, cree tres archivos, a saber:login.php, enter_email.php, new_pass.php:

Cada uno de estos tres archivos representa los tres pasos que describimos anteriormente. Abre cada uno de ellos y pega los siguientes códigos en ellos:

iniciar sesión.php:

<?php include('app_logic.php'); ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Password Reset PHP</title>
	<link rel="stylesheet" href="main.css">
</head>
<body>
	<form class="login-form" action="login.php" method="post">
		<h2 class="form-title">Login</h2>
		<!-- form validation messages -->
		<?php include('messages.php'); ?>
		<div class="form-group">
			<label>Username or Email</label>
			<input type="text" value="<?php echo $user_id; ?>" name="user_id">
		</div>
		<div class="form-group">
			<label>Password</label>
			<input type="password" name="password">
		</div>
		<div class="form-group">
			<button type="submit" name="login_user" class="login-btn">Login</button>
		</div>
		<p><a href="enter_email.php">Forgot your password?</a></p>
	</form>
</body>
</html>

enter_email.php:

<?php include('app_logic.php'); ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Password Reset PHP</title>
	<link rel="stylesheet" href="main.css">
</head>
<body>
	<form class="login-form" action="enter_email.php" method="post">
		<h2 class="form-title">Reset password</h2>
		<!-- form validation messages -->
		<?php include('messages.php'); ?>
		<div class="form-group">
			<label>Your email address</label>
			<input type="email" name="email">
		</div>
		<div class="form-group">
			<button type="submit" name="reset-password" class="login-btn">Submit</button>
		</div>
	</form>
</body>
</html>

nueva_contraseña.php:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Password Reset PHP</title>
	<link rel="stylesheet" href="main.css">
</head>
<body>
	<form class="login-form" action="new_password.php" method="post">
		<h2 class="form-title">New password</h2>
		<!-- form validation messages -->
		<?php include('messages.php'); ?>
		<div class="form-group">
			<label>New password</label>
			<input type="password" name="new_pass">
		</div>
		<div class="form-group">
			<label>Confirm new password</label>
			<input type="password" name="new_pass_c">
		</div>
		<div class="form-group">
			<button type="submit" name="new_password" class="login-btn">Submit</button>
		</div>
	</form>
</body>
</html>

En cada uno de estos archivos, verá que incluimos tres archivos que aún no hemos creado, a saber, app_logic.php , message.php,file y main.css. El primero maneja toda la lógica de nuestra aplicación, como consultar la base de datos, enviar correos electrónicos al usuario y más; el segundo muestra mensajes de retroalimentación al usuario, como cuando ingresa un correo electrónico incorrecto, el tercero es el estilo de la aplicación.

Cree estos archivos en la carpeta de recuperación de contraseña. En el archivo main.css, agregue este código de estilo:

principal.css:

body {
	background: #3b5998;
	font-size: 1.1em;
	font-family: sans-serif;
}
a {
	text-decoration: none;
}
form {
	width: 25%;
	margin: 70px auto;
	background: white;
	padding: 10px;
	border-radius: 3px;
}
h2.form-title {
	text-align: center;
}
input {
	display: block;
	box-sizing: border-box;
	width: 100%;
	padding: 8px;
}
form .form-group {
	margin: 10px auto;
}
form button {
	width: 100%;
	border: none;
	color: white;
	background: #3b5998;
	padding: 15px;
	border-radius: 5px;
}
.msg {
	margin: 5px auto;
	border-radius: 5px;
	border: 1px solid red;
	background: pink;
	text-align: left;
	color: brown;
	padding: 10px;
}

app_logic.php:

<?php 

session_start();
$errors = [];
$user_id = "";
// connect to database
$db = mysqli_connect('localhost', 'root', '', 'password-reset-php');

// LOG USER IN
if (isset($_POST['login_user'])) {
  // Get username and password from login form
  $user_id = mysqli_real_escape_string($db, $_POST['user_id']);
  $password = mysqli_real_escape_string($db, $_POST['password']);
  // validate form
  if (empty($user_id)) array_push($errors, "Username or Email is required");
  if (empty($password)) array_push($errors, "Password is required");

  // if no error in form, log user in
  if (count($errors) == 0) {
    $password = md5($password);
    $sql = "SELECT * FROM users WHERE username='$user_id' OR email='$user_id' AND password='$password'";
    $results = mysqli_query($db, $sql);

    if (mysqli_num_rows($results) == 1) {
      $_SESSION['username'] = $user_id;
      $_SESSION['success'] = "You are now logged in";
      header('location: index.php');
    }else {
      array_push($errors, "Wrong credentials");
    }
  }
}

/*
  Accept email of user whose password is to be reset
  Send email to user to reset their password
*/
if (isset($_POST['reset-password'])) {
  $email = mysqli_real_escape_string($db, $_POST['email']);
  // ensure that the user exists on our system
  $query = "SELECT email FROM users WHERE email='$email'";
  $results = mysqli_query($db, $query);

  if (empty($email)) {
    array_push($errors, "Your email is required");
  }else if(mysqli_num_rows($results) <= 0) {
    array_push($errors, "Sorry, no user exists on our system with that email");
  }
  // generate a unique random token of length 100
  $token = bin2hex(random_bytes(50));

  if (count($errors) == 0) {
    // store token in the password-reset database table against the user's email
    $sql = "INSERT INTO password_reset(email, token) VALUES ('$email', '$token')";
    $results = mysqli_query($db, $sql);

    // Send email to user with the token in a link they can click on
    $to = $email;
    $subject = "Reset your password on examplesite.com";
    $msg = "Hi there, click on this <a href=\"new_password.php?token=" . $token . "\">link</a> to reset your password on our site";
    $msg = wordwrap($msg,70);
    $headers = "From: [email protected]";
    mail($to, $subject, $msg, $headers);
    header('location: pending.php?email=' . $email);
  }
}

// ENTER A NEW PASSWORD
if (isset($_POST['new_password'])) {
  $new_pass = mysqli_real_escape_string($db, $_POST['new_pass']);
  $new_pass_c = mysqli_real_escape_string($db, $_POST['new_pass_c']);

  // Grab to token that came from the email link
  $token = $_SESSION['token'];
  if (empty($new_pass) || empty($new_pass_c)) array_push($errors, "Password is required");
  if ($new_pass !== $new_pass_c) array_push($errors, "Password do not match");
  if (count($errors) == 0) {
    // select email address of user from the password_reset table 
    $sql = "SELECT email FROM password_reset WHERE token='$token' LIMIT 1";
    $results = mysqli_query($db, $sql);
    $email = mysqli_fetch_assoc($results)['email'];

    if ($email) {
      $new_pass = md5($new_pass);
      $sql = "UPDATE users SET password='$new_pass' WHERE email='$email'";
      $results = mysqli_query($db, $sql);
      header('location: index.php');
    }
  }
}
?>

Aquí se ven tres bloques de sentencias if. Estas declaraciones manejan tres acciones, a saber, el inicio de sesión del usuario, recibir un correo electrónico de restablecimiento y recibir una nueva contraseña. En el segundo bloque, después de recibir la dirección de correo electrónico del usuario, el usuario es redirigido a una página pendiente.php. Esta página simplemente muestra un mensaje que le dice al usuario que se ha enviado un correo electrónico a su dirección de correo electrónico que puede usar para restablecer su contraseña.

Cree un archivoending.php en la carpeta raíz de nuestro proyecto y agregue este código dentro:

pendiente.php:

<?php include('app_logic.php'); ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Password Reset PHP</title>
	<link rel="stylesheet" href="main.css">
</head>
<body>

	<form class="login-form" action="login.php" method="post" style="text-align: center;">
		<p>
			We sent an email to  <b><?php echo $_GET['email'] ?></b> to help you recover your account. 
		</p>
	    <p>Please login into your email account and click on the link we sent to reset your password</p>
	</form>
		
</body>
</html>

message.php es un archivo que contiene el fragmento de código para mostrar mensajes de error en el formulario. Ábrelo y pega este código dentro:

mensajes.php:

<?php  if (count($errors) > 0) : ?>
  <div class="msg">
  	<?php foreach ($errors as $error) : ?>
  	  <span><?php echo $error ?></span>
  	<?php endforeach ?>
  </div>
<?php  endif ?>

Ahora abra este proyecto en su navegador en http://localhost/password-recovery/login.php y juegue con él.

Nota: Usamos la función mail() de PHP para enviar correos electrónicos al usuario. Esta función no puede enviar correos desde localhost. Solo puede hacerlo utilizando un servidor alojado en Internet. Sin embargo, podemos usar una aplicación de correo de prueba para simular el envío de correos electrónicos si desea tener una demostración en su sistema local.

Conclusión

Gracias por seguir este tutorial hasta el final. Espero que la explicación haya sido lo suficientemente clara y hayas aprendido algo que pueda serte de ayuda en tu desarrollo web. Si tiene algún problema o inquietud, no olvide dejarlos en los comentarios a continuación y me pondré en contacto con usted.

¡Que tengas un buen día!