sql >> Database >  >> RDS >> Mysql

Wachtwoord reset systeem in PHP

Een zeer belangrijk kenmerk van een goede lidmaatschapswebsite is een systeem voor het opnieuw instellen van het wachtwoord, omdat sommige gebruikers hun wachtwoord zullen vergeten. In deze zelfstudie schets ik de stappen die nodig zijn om het wachtwoord van een gebruiker te herstellen; we zullen in deze tutorial ook een dergelijk systeem implementeren met behulp van PHP en een MySQL-database.

Het hele proces van het implementeren van een dergelijk systeem kan worden onderverdeeld in 3 hoofdstappen. Laten we, om de uitleg te vergemakkelijken, deze stappen analyseren in termen van de formulieren die we zullen presenteren aan de gebruiker om in te vullen:

  1. Inlogformulier:  Dit formulier gebruikt de combinatie van gebruikersnaam en wachtwoord van een gebruiker en logt in als deze op het systeem is geregistreerd. Op dit formulier geven we een "Wachtwoord vergeten?" link voor het geval de gebruiker zijn wachtwoord is vergeten en het opnieuw moet instellen.
  2. E-mailformulier:  Als de gebruiker zijn wachtwoord is vergeten, kan hij klikken op "Wachtwoord vergeten?" link op de inlogpagina om het opnieuw in te stellen. Als ze op deze link klikken, gaan ze naar een andere pagina waar ze worden gevraagd het e-mailadres in te voeren. Wanneer het e-mailadres dat ze verstrekken niet in onze gebruikerstabel in de database staat, zullen we een foutmelding weergeven die zegt:"Er bestaat geen dergelijke gebruiker op ons systeem". Als de gebruiker daarentegen wel bestaat, genereren we een unieke token (een unieke willekeurige tekenreeks) en slaan we deze token samen met dat e-mailadres op in de tabel password_resets in de database. Dan sturen we ze een e-mail met die token in een link. Wanneer ze op de link klikken in de e-mail die we ze hebben gestuurd, worden ze teruggestuurd naar onze website op een pagina waarop ze een ander formulier krijgen.
  3. Nieuw wachtwoord Formulier:  Zodra de gebruiker weer op onze website is, pakken we het token dat van de link komt en slaan we het op in een sessievariabele. Vervolgens zullen we hen een formulier voorleggen waarin hen wordt gevraagd een nieuw wachtwoord in te voeren voor hun account op onze website. Wanneer het nieuwe wachtwoord is ingediend, zullen we de tabel password_resets doorzoeken voor het record dat dat token heeft dat zojuist uit de link in de e-mail kwam. Als het token wordt gevonden in de tabel password_resets, dan zijn we er zeker van dat de gebruiker is wie ze zijn en dat ze op de link in hun e-mail hebben geklikt. Op dit moment pakken we het e-mailadres van de gebruiker uit de tabel password_resets (vergeet niet dat we het token naast hun e-mailadres hadden opgeslagen) en gebruiken we dat e-mailadres om de gebruiker op te halen uit de tabel met gebruikers en hun wachtwoord bij te werken.

Hoop dat dat duidelijk genoeg is. Zo niet, blijf dan gewoon in de buurt en het zal duidelijker worden naarmate we het implementeren.

Implementatie

Maak een database met de naam password_recovery en maak in die database twee tabellen, namelijk gebruikers en password_resets met de volgende velden:

gebruikers:

+----+-----------+--------------+------------+
|     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     |
+----------------+--------------+------------+

Opmerking: Deze applicatie vereist dat de gebruiker al op het systeem is geregistreerd. Maar we zullen het gedeelte over gebruikersregistratie in deze zelfstudie niet behandelen, omdat het al op deze site is behandeld. Je kunt die tutorial eerst volgen (ik raad je aan dat te doen) of niet, maar houd er rekening mee dat we een gebruiker in onze gebruikerstabel in de database moeten hebben voordat we verder kunnen gaan met het opnieuw instellen van hun wachtwoord. Dus voeg op de een of andere manier een gebruiker toe aan uw mysql-database. U kunt een tool zoals PHPMyAdmin gebruiken en ervoor zorgen dat u het wachtwoord versleutelt met md5().

Maak nu een projectmap met de naam wachtwoordherstel en zorg ervoor dat deze map in uw servermap staat (htdocs-map of www-map). Maak in die map drie bestanden aan, namelijk:login.php, enter_email.php, new_pass.php:

Elk van deze drie bestanden vertegenwoordigt de drie stappen die we eerder hebben beschreven. Open ze allemaal en plak de volgende codes erin:

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>

In elk van deze bestanden zie je dat we drie bestanden opnemen die we nog niet hebben gemaakt, namelijk de app_logic.php, messages.php,file en main.css. De eerste behandelt alle logica van onze applicatie, zoals het doorzoeken van de database, het verzenden van e-mail naar de gebruiker en meer; de tweede geeft feedbackberichten weer aan de gebruiker, bijvoorbeeld wanneer ze een verkeerde e-mail invoeren, de derde is de vormgeving van de applicatie.

Maak deze bestanden in de map voor wachtwoordherstel. Voeg in het main.css-bestand deze stijlcode toe:

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

Hier zie je drie blokken met if-statements. Deze verklaringen behandelen drie acties, namelijk inloggen door de gebruiker, het ontvangen van een reset-e-mail en het ontvangen van een nieuw wachtwoord. In het tweede blok, na ontvangst van het e-mailadres van de gebruiker, wordt de gebruiker doorgestuurd naar een pending.php-pagina. Deze pagina geeft eenvoudigweg een bericht weer dat de gebruiker vertelt dat er een e-mail is verzonden naar zijn e-mailadres dat hij kan gebruiken om zijn wachtwoord opnieuw in te stellen.

Maak pending.php aan in de hoofdmap van ons project en voeg deze code erin toe:

in afwachting.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 is een bestand dat het codefragment bevat voor het weergeven van foutmeldingen op het formulier. Open het en plak deze code erin:

berichten.php:

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

Open dit project nu in uw browser op http://localhost/password-recovery/login.php en speel ermee.

Opmerking: We hebben de functie mail() van PHP gebruikt om e-mail naar de gebruiker te sturen. Deze functie kan geen e-mails verzenden vanaf localhost. Het kan dit alleen doen met behulp van een server die op internet wordt gehost. We kunnen echter een testmailtoepassing gebruiken om het verzenden van e-mails te simuleren als u een demo op uw lokale systeem wilt hebben.

Conclusie

Bedankt voor het volgen van deze tutorial tot het einde. Ik hoop dat de uitleg duidelijk genoeg was en dat je iets hebt geleerd dat je kan helpen bij je webontwikkeling. Als je problemen of opmerkingen hebt, vergeet ze dan niet in de reacties hieronder te plaatsen, dan neem ik contact met je op.

Fijne dag nog!


  1. Lijst met talen die door Oracle Database worden ondersteund

  2. Bindende queryparameters op naam met ODP.NET

  3. Mysql invoegen in 2 tabellen

  4. Toon alle query's die naar een Oracle-database komen