Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Sistema de redefinição de senha em PHP


Uma característica muito importante de qualquer bom site de associação é um sistema de redefinição de senha, porque alguns usuários podem esquecer sua senha. Neste tutorial, descrevo as etapas envolvidas na recuperação da senha de um usuário; também estaremos implementando tal sistema usando PHP e um banco de dados MySQL neste tutorial.

Todo o processo de implementação de tal sistema pode ser dividido em 3 etapas principais. Para facilitar a explicação, vamos analisar estes passos em termos dos formulários que apresentaremos para o usuário preencher:
  1. Formulário de login:  Este formulário usa a combinação de nome de usuário e senha de um usuário e faz login se ele estiver registrado no sistema. Neste formulário, fornecemos um "Esqueceu sua senha?" link caso o usuário tenha esquecido a senha e precise redefini-la.
  2. Formulário de e-mail:  Se o usuário esqueceu sua senha, ele pode clicar no botão "Esqueceu sua senha?" link na página de login para redefini-lo. Ao clicar nesse link, eles serão direcionados para outra página que solicita que eles insiram o e-mail. Quando o endereço de e-mail fornecido não estiver em nossa tabela de usuários no banco de dados, exibiremos uma mensagem de erro que diz "Nenhum usuário existe em nosso sistema". Se, por outro lado, o usuário existir, geraremos um token exclusivo (uma string aleatória exclusiva) e armazenaremos esse token junto com esse endereço de e-mail na tabela password_resets no banco de dados. Em seguida, enviaremos a eles um e-mail com esse token em um link. Quando eles clicarem no link do e-mail que enviamos, eles serão enviados de volta ao nosso site em uma página que os apresentará com outro formulário.
  3. Formulário de nova senha:  Quando o usuário estiver de volta ao nosso site, pegaremos o token que vem do link e o armazenaremos em uma variável de sessão. Em seguida, apresentaremos a eles um formulário que solicita que eles insiram uma nova senha para sua conta em nosso site. Quando a nova senha for enviada, consultaremos a tabela password_resets para o registro que possui esse token que acabou de vir do link no e-mail. Se o token for encontrado na tabela password_resets, estamos confiantes de que o usuário é quem ele é e que clicaram no link em seu e-mail. Neste momento, pegamos o e-mail do usuário na tabela password_resets (lembre-se de que salvamos o token ao lado do endereço de e-mail) e ​​usamos esse e-mail para buscar o usuário na tabela users e atualizar a senha.





Espero que esteja claro o suficiente. Caso contrário, fique por aqui e ficará mais claro à medida que implementamos.

Implementação


Crie um banco de dados chamado password_recovery e, nesse banco de dados, crie duas tabelas, users e password_resets com os seguintes campos:

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

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

Observação: Este aplicativo exige que o usuário já esteja cadastrado no sistema. Mas, não abordaremos a parte de registro do usuário neste tutorial porque ela já foi abordada neste site. Você pode seguir esse tutorial primeiro (recomendo) ou não, mas lembre-se de que precisamos ter um usuário em nossa tabela de usuários no banco de dados antes de podermos redefinir sua senha. Então, de uma forma ou de outra, adicione um usuário ao seu banco de dados mysql. Você pode usar uma ferramenta como PHPMyAdmin e certifique-se de criptografar a senha usando md5().

Agora crie uma pasta de projeto chamada recuperação de senha e verifique se essa pasta está no diretório do servidor (pasta htdocs ou pasta www). Nessa pasta, crie três arquivos a saber:login.php, enter_email.php, new_pass.php:



Cada um desses três arquivos representa as três etapas que descrevemos anteriormente. Abra cada um deles e cole os seguintes códigos neles:

login.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>

new_pass.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>

Em cada um desses arquivos, você vê que estamos incluindo três arquivos que ainda não criamos, ou seja, app_logic.php , messages.php,file e main.css. O primeiro trata de toda a lógica da nossa aplicação como consultar o banco de dados, enviar email para o usuário e muito mais; o segundo exibe mensagens de feedback para o usuário, como quando ele digita um email errado, o terceiro é o estilo do aplicativo.

Crie esses arquivos na pasta de recuperação de senha. No arquivo main.css, adicione este código de estilo:

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

Aqui você vê três blocos de instruções if. Essas instruções lidam com três ações, a saber, login do usuário, recebimento de e-mail de redefinição e recebimento de nova senha. No segundo bloco, após receber o endereço de e-mail do usuário, o usuário está sendo redirecionado para uma página pendente.php. Esta página simplesmente exibe uma mensagem informando ao usuário que um e-mail foi enviado para seu endereço de e-mail que ele pode usar para redefinir sua senha.

Crie pendente.php na pasta raiz do nosso projeto e adicione este código dentro dela:

pendente.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>

messages.php é um arquivo que contém o trecho de código para exibir mensagens de erro no formulário. Abra-o e cole este código dentro dele:

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

Agora abra este projeto no seu navegador em http://localhost/password-recovery/login.php e brinque com ele.

Observação: Usamos a função mail() do PHP para enviar e-mail ao usuário. Esta função não pode enviar e-mails do localhost. Só pode fazê-lo usando um servidor que está hospedado na internet. No entanto, podemos usar um aplicativo de e-mail de teste para simular o envio de e-mails se você quiser ter uma demonstração em seu sistema local.

Conclusão


Obrigado por seguir este tutorial até o final. Espero que a explicação tenha sido clara o suficiente e que você tenha aprendido algo que possa te ajudar no seu desenvolvimento web. Se você tiver quaisquer problemas ou preocupações, não se esqueça de deixá-los nos comentários abaixo e eu entrarei em contato com você.

Tenha um bom dia!