sql >> Databasteknik >  >> RDS >> Mysql

Lösenordsåterställningssystem i PHP

En mycket viktig egenskap hos alla bra medlemswebbplatser är ett lösenordsåterställningssystem eftersom vissa användare är skyldiga att glömma sitt lösenord. I den här handledningen beskriver jag stegen som är involverade i att återställa en användares lösenord; vi kommer också att implementera ett sådant system med PHP och en MySQL-databas i denna handledning.

Hela processen med att implementera ett sådant system kan delas upp i tre huvudsteg. För att underlätta förklaringen, låt oss analysera dessa steg i form av formulären som vi kommer att presentera för användaren att fylla i:

  1. Inloggningsformulär:  Det här formuläret tar en användares användarnamn och lösenordskombination och loggar in dem om de är registrerade i systemet. På det här formuläret tillhandahåller vi ett "Glömt ditt lösenord?" länk om användaren har glömt sitt lösenord och behöver återställa det.
  2. E-postformulär:  Om användaren har glömt sitt lösenord kan de klicka på "Glömt ditt lösenord?" länken på inloggningssidan för att återställa den. Om du klickar på den här länken kommer de till en annan sida som uppmanar dem att ange e-postmeddelandet. När e-postadressen de anger inte finns i vår användartabell i databasen kommer vi att visa ett felmeddelande som säger "Ingen sådan användare finns på vårt system". Om användaren å andra sidan finns kommer vi generera en unik token (en unik slumpmässig sträng) och lagra denna token tillsammans med den e-postadressen i password_resets-tabellen i databasen. Sedan skickar vi ett e-postmeddelande till dem som har den token i en länk. När de klickar på länken i e-postmeddelandet vi skickade dem skickas de tillbaka till vår webbplats på en sida som visar dem med ett annat formulär.
  3. Formulär för nytt lösenord:  När användaren är tillbaka på vår webbplats igen kommer vi att ta tag i token som kommer från länken och lagra den i en sessionsvariabel. Sedan kommer vi att presentera dem med ett formulär som ber dem att ange ett nytt lösenord för sitt konto på vår hemsida. När det nya lösenordet har skickats kommer vi att fråga tabellen password_resets efter posten som har den token som just kom från länken i posten. Om token hittas i password_resets-tabellen är vi säkra på att användaren är den de är och att de klickade på länken i sin e-post. Vid det här laget tar vi tag i användarens e-post från tabellen password_resets (kom ihåg att vi hade sparat token bredvid deras e-postadress) och använder den e-postadressen för att hämta användaren från användartabellen och uppdatera deras lösenord.

Hoppas det är tillräckligt tydligt. Om inte, håll dig kvar så blir det tydligare när vi implementerar.

Implementering

Skapa en databas som heter password_recovery och i den databasen, skapa två tabeller, nämligen användare och password_resets med följande fält:

användare:

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

Obs! Denna applikation kräver att användaren redan är registrerad på systemet. Men vi kommer inte att täcka användarregistreringsdelen i den här handledningen eftersom den redan har behandlats på den här webbplatsen. Du kan följa den handledningen först (jag rekommenderar att du gör det) eller inte, men kom ihåg att vi måste ha en användare i vår användartabell i databasen innan vi kan fortsätta att återställa deras lösenord. Så på ett eller annat sätt, lägg till en användare till din mysql-databas. Du kan använda ett verktyg som PHPMyAdmin och se till att du krypterar lösenordet med md5().

Skapa nu en projektmapp som heter lösenordsåterställning och se till att den här mappen finns i din serverkatalog (htdocs-mappen eller www-mappen). Skapa tre filer i den mappen, nämligen:login.php, enter_email.php, new_pass.php:

Var och en av dessa tre filer representerar de tre steg som vi beskrev tidigare. Öppna var och en av dem och klistra in följande koder i dem:

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>

I var och en av dessa filer ser du att vi inkluderar tre filer som vi ännu inte har skapat, nämligen app_logic.php , messages.php,file och main.css. Den första hanterar all logik i vår applikation, såsom att fråga databasen, skicka e-post till användaren och mer; den andra visar feedbackmeddelanden till användaren som när de anger fel e-post, den tredje är stilen på applikationen.

Skapa dessa filer i mappen för lösenordsåterställning. Lägg till denna stilkod i filen main.css:

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

Här ser du tre block av if-satser. Dessa uttalanden hanterar tre åtgärder, nämligen användarinloggning, att ta emot återställningsmeddelanden och ta emot nytt lösenord. I det andra blocket, efter att ha mottagit användarens e-postadress, omdirigeras användaren till en väntande.php-sida. Den här sidan visar helt enkelt ett meddelande som talar om för användaren att ett e-postmeddelande har skickats till deras e-postadress som de kan använda för att återställa sitt lösenord.

Skapa pending.php i rotmappen för vårt projekt och lägg till denna kod i den:

pending.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 är en fil som innehåller kodavsnittet för att visa felmeddelanden i formuläret. Öppna den och klistra in den här koden i den:

messages.php:

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

Öppna nu det här projektet i din webbläsare på http://localhost/password-recovery/login.php och lek med det.

Obs! Vi använde PHPs mail()-funktion för att skicka e-post till användaren. Den här funktionen kan inte skicka e-post från localhost. Det kan bara göra det med en server som finns på internet. Vi kan dock använda ett testprogram för att simulera sändning av e-postmeddelanden om du vill ha en demo på ditt lokala system.

Slutsats

Tack för att du följer denna handledning till slutet. Jag hoppas att förklaringen var tillräckligt tydlig och att du lärde dig något som kan vara till hjälp för dig i din webbutveckling. Om du har några problem eller funderingar, glöm inte att släppa dem i kommentarerna nedan så kommer jag att kontakta dig.

Ha en bra dag!


  1. Sväva högre i molnet med MariaDB SkySQL

  2. Hur utför jag en infogning och returnerar insatt identitet med Dapper?

  3. Mysql-rekursion?

  4. Vanliga misstag av DBA i MS SQL Server