Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Hệ thống đặt lại mật khẩu trong PHP

Một tính năng rất quan trọng của bất kỳ trang web thành viên tốt nào là hệ thống đặt lại mật khẩu vì một số người dùng nhất định quên mật khẩu của họ. Trong hướng dẫn này, tôi phác thảo các bước liên quan đến việc khôi phục mật khẩu của người dùng; chúng tôi cũng sẽ triển khai một hệ thống như vậy bằng PHP và cơ sở dữ liệu MySQL trong hướng dẫn này.

Toàn bộ quá trình thực hiện một hệ thống như vậy có thể được chia thành 3 bước chính. Để dễ dàng giải thích, hãy phân tích các bước sau về các biểu mẫu mà chúng tôi sẽ trình bày để người dùng điền vào:

  1. Biểu mẫu Đăng nhập: Biểu mẫu này lấy tên người dùng và mật khẩu kết hợp của một người dùng và đăng nhập họ nếu họ đã đăng ký trên hệ thống. Trên biểu mẫu này, chúng tôi cung cấp thông báo "Quên mật khẩu của bạn?" trong trường hợp người dùng quên mật khẩu và cần đặt lại mật khẩu.
  2. Biểu mẫu Email: Nếu người dùng quên mật khẩu, họ có thể nhấp vào nút "Quên mật khẩu của bạn?" liên kết trên trang đăng nhập để đặt lại nó. Nhấp vào liên kết này sẽ đưa họ đến một trang khác nhắc họ nhập email. Khi địa chỉ email họ cung cấp không có trong bảng người dùng của chúng tôi trong cơ sở dữ liệu, chúng tôi sẽ hiển thị và thông báo lỗi cho biết "Không có người dùng như vậy tồn tại trên hệ thống của chúng tôi". Mặt khác, nếu người dùng tồn tại, chúng tôi sẽ tạo một mã thông báo duy nhất (một chuỗi ngẫu nhiên duy nhất) và lưu trữ mã thông báo này cùng với địa chỉ email đó trong bảng password_resets trong cơ sở dữ liệu. Sau đó, chúng tôi sẽ gửi cho họ một email có mã thông báo đó trong một liên kết. Khi họ nhấp vào liên kết trong email chúng tôi đã gửi cho họ, họ sẽ được đưa trở lại trang web của chúng tôi trên một trang hiển thị cho họ một biểu mẫu khác.
  3. Biểu mẫu mật khẩu mới: Khi người dùng quay lại trang web của chúng tôi một lần nữa, chúng tôi sẽ lấy mã thông báo đến từ liên kết và lưu trữ nó trong một biến phiên. Sau đó, chúng tôi sẽ đưa cho họ một biểu mẫu yêu cầu họ nhập mật khẩu mới cho tài khoản của họ trên trang web của chúng tôi. Khi mật khẩu mới được gửi, chúng tôi sẽ truy vấn bảng password_resets để tìm bản ghi có mã thông báo đó vừa đến từ liên kết trong thư. Nếu mã thông báo được tìm thấy trên bảng password_resets, thì chúng tôi tin chắc rằng họ là người dùng của họ và họ đã nhấp vào liên kết trong thư của họ. Tại thời điểm này, chúng tôi lấy email của người dùng từ bảng password_resets (hãy nhớ rằng chúng tôi đã lưu mã thông báo cùng với địa chỉ email của họ) và sử dụng email đó để tìm nạp người dùng từ bảng người dùng và cập nhật mật khẩu của họ.

Hy vọng điều đó đủ rõ ràng. Nếu không thì chỉ cần tiếp tục và nó sẽ trở nên rõ ràng hơn khi chúng tôi thực hiện.

Thực hiện

Tạo một cơ sở dữ liệu có tên là password_recovery và trong cơ sở dữ liệu đó, hãy tạo hai bảng là người dùng và password_resets với các trường sau:

người dùng:

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

Lưu ý: Ứng dụng này yêu cầu người dùng đã được đăng ký trên hệ thống. Tuy nhiên, chúng tôi sẽ không đề cập đến phần đăng ký người dùng trong hướng dẫn này vì nó đã được đề cập trên trang web này. Bạn có thể làm theo hướng dẫn đó trước (tôi khuyên bạn nên làm) hoặc không, nhưng hãy nhớ rằng chúng tôi cần có một người dùng trong bảng người dùng của chúng tôi trong cơ sở dữ liệu trước khi chúng tôi có thể tiến hành đặt lại mật khẩu của họ. Vì vậy, bằng cách này hay cách khác, hãy thêm một người dùng vào cơ sở dữ liệu mysql của bạn. Bạn có thể sử dụng một công cụ như PHPMyAdmin và đảm bảo rằng bạn mã hóa mật khẩu bằng md5 ().

Bây giờ, hãy tạo một thư mục dự án có tên là password-recovery và đảm bảo rằng thư mục này nằm trong thư mục máy chủ của bạn (thư mục htdocs hoặc thư mục www). Trong thư mục đó, tạo ba tệp:login.php, enter_email.php, new_pass.php:

Mỗi tệp trong số ba tệp này đại diện cho ba bước mà chúng tôi đã nêu trước đó. Mở từng người trong số họ và dán các mã sau vào đó:

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>

Trong mỗi tệp này, bạn thấy rằng chúng tôi đang bao gồm ba tệp mà chúng tôi chưa tạo, đó là app_logic.php, messages.php, tệp và main.css. Đầu tiên xử lý tất cả logic của ứng dụng của chúng tôi như truy vấn cơ sở dữ liệu, gửi email cho người dùng và hơn thế nữa; thứ hai hiển thị thông báo phản hồi cho người dùng chẳng hạn như khi họ nhập sai email, thứ ba là kiểu dáng của ứng dụng.

Tạo các tệp này trong thư mục khôi phục mật khẩu. Trong tệp main.css, hãy thêm mã kiểu này:

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

Ở đây bạn sẽ thấy ba khối lệnh if. Các câu lệnh này xử lý ba hành động cụ thể là đăng nhập của người dùng, nhận email đặt lại và nhận mật khẩu mới. Trong khối thứ hai, sau khi nhận được địa chỉ email của người dùng, người dùng đang được chuyển hướng đến trang.php đang chờ xử lý. Trang này chỉ hiển thị một thông báo cho người dùng biết rằng một email đã được gửi đến địa chỉ email của họ mà họ có thể sử dụng để đặt lại mật khẩu của mình.

Tạo pending.php trong thư mục gốc của dự án của chúng tôi và thêm mã này vào bên trong nó:

đang chờ xử lý.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 là một tệp chứa đoạn mã để hiển thị thông báo lỗi trên biểu mẫu. Mở nó ra và dán mã này vào bên trong nó:

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

Bây giờ, hãy mở dự án này trên trình duyệt của bạn tại http://localhost/password-recovery/login.php và chơi với nó.

Lưu ý: Chúng tôi đã sử dụng hàm mail () của PHP để gửi email đến người dùng. Chức năng này không thể gửi thư từ localhost. Nó chỉ có thể làm như vậy bằng cách sử dụng một máy chủ được lưu trữ trên internet. Tuy nhiên, chúng tôi có thể sử dụng ứng dụng thư thử nghiệm để mô phỏng việc gửi email nếu bạn muốn có bản demo trên hệ thống cục bộ của mình.

Kết luận

Cảm ơn bạn đã theo dõi bài hướng dẫn này đến cuối cùng. Tôi hy vọng lời giải thích đủ rõ ràng và bạn đã học được điều gì đó có thể giúp ích cho bạn trong quá trình phát triển web của bạn. Nếu bạn có bất kỳ vấn đề hoặc mối quan tâm nào, đừng quên để lại trong phần bình luận bên dưới và tôi sẽ liên hệ với bạn.

Chúc một ngày tốt lành!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kết nối từ xa Mysql Ubuntu

  2. Ví dụ về DATE_SUB () - MySQL

  3. MySQL:Giao dịch so với Bảng khóa

  4. JSON_OBJECTAGG () - Tạo một đối tượng JSON từ kết quả truy vấn trong MySQL

  5. Đánh giá về các chức năng của cửa sổ phân tích mới trong MySQL 8.0