Hướng dẫn xây dựng trang khôi phục mật khẩu trong WordPress

07/05/2022 Wordpress 17153 lượt xem
Lưu bài viết

Chào các bạn để tiếp tục chuỗi series bài viết về Custom tài khoản WordPress, hôm nay mình sẽ giới thiệu các bạn cách để tạo một trang khôi phục mật khẩu trong WordPress. Nếu các bạn chưa xem các bài viết cũ của mình, hãy đọc nó trước nhé!

Trang khôi phục mật khẩu mặc định của WordPress

Theo mặc định ngoài trang đăng nhập, WordPress còn cung cấp cho các bạn một trang để khôi phục lại mật khẩu. Các bạn có thể truy cập trang đó bằng đường dẫn domain/wp-login.php?action=lostpassword.

trang quên mật khẩu wordpress

Nhưng với giao diện mặc định của WordPress, nó sẽ không đồng nhất với thiết kế của website bạn.

Vì vậy mình sẽ hướng dẫn các bạn cách tạo một trang khôi phục mật khẩu tuỳ chỉnh. Việc này sẽ giúp các bạn nâng cao trải nghiệm người dùng cũng như tính chuyên nghiệp cho website.

Tạo trang khôi phục mật khẩu WordPress

Giống như các bài viết trước, các bạn phải tạo một page mới trong WordPress. Nếu các bạn vẫn chưa xem các bài viết trước thì hãy nhấp vào đây nhé!

Cụ thể ở đây mình sẽ tạo một page mới có tiêu đề là Quên mật khẩu, đường dẫn của page này sẽ là domain/quen-mat-khau. Sau đó mình sẽ tạo một file PHP mới trong theme mình đang sử dụng, file PHP đó sẽ có cú pháp page-quen-mat-khau.php.

Các bạn hãy copy đoạn code dưới đây vào file page-quen-mat-khau.php mới tạo:

<?php get_header(); ?>

<main id="site-content">
    <div class="section-inner">

        <?php
        $home_url = get_home_url();
        if ( is_user_logged_in() ) {

            echo 'Bạn đã đăng nhập rồi. <a href="'.wp_logout_url($home_url).'">Đăng xuất</a> ?';

        } else {
        ?>
            <h1>Quên mật khẩu</h1>
            <hr>
            <form id="hk-forgotpwd" action="<?php echo get_home_url() . '/quen-mat-khau'; ?>">
                <?php wp_nonce_field( 'form_forgot_password' ); ?>
                <div id="hk-message"></div>
                <p style="display:none" id="hk-success">
                    Đã gửi thông tin khôi phục password vào email của bạn. Hãy kiểm tra email!
                </p>
                <p>
                    <input type="email" name="email" id="email" placeholder="Email" required>
                </p>
                <p class="text-center mb-0">
                    <button class="form-submit" type="submit">
                        Lấy lại mật khẩu
                    </button>
                </p>
            </form>

        <?php } ?>

    </div>
</main>

<?php get_footer(); ?>

Đây là giao diện bạn có thể đạt được sau khi sử dụng đoạn code trên của mình:

giao diện quên mật khẩu

Giải thích một chút về code tạo trang khôi phục mật khẩu WordPress

Nếu các bạn đã xem bài viết mình hướng dẫn xây dựng trang đăng ký trong WordPress, các bạn sẽ nhận ra sự giống nhau ở phần này.

Ở đây mình cũng sử dụng câu lệnh điều kiện ở dòng 8 để kiểm tra người dùng đã đăng nhập chưa. Và ở dòng 17, mình vẫn tiếp tục sử dụng hàm wp_nonce_field với mục đích bảo mật.

Phần còn lại chỉ là các thẻ HTML để tạo form.

Vì hiện tại mình đang dùng theme twentytwenty của WordPress nên có thể giao diện sẽ khác của bạn một chút.

Gửi dữ liệu lên server

Sau khi người dùng nhập dữ liệu vào form, thì việc tiếp theo chúng ta phải gửi dữ liệu đó lên phía server. Trong bài viết này mình vẫn sử dụng AJAX để gửi dữ liệu. Nếu các bạn chưa biết AJAX là gì thì có thể xem các bài viết hướng dẫn về AJAX trong WordPress của mình trước nhé.

Hãy thêm đoạn code dưới đây vào file footer.php. Nếu theme của bạn đã khai báo jQuery rồi thì hãy xoá dòng đầu tiên đi.

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
(function($){  
	$(document).ready(function(){
		var ajaxUrl = '<?php echo admin_url('admin-ajax.php'); ?>';
		$('#hk-forgotpwd').submit(function(e) {
			e.preventDefault();
			var data = {};
			var ArrayForm = $(this).serializeArray();
			$.each(ArrayForm, function() {
				data[this.name] = this.value;
			});

			$.ajax({
				type: "POST",
				url: ajaxUrl,
				data: {
					'action': 'ForgotPassword',
					'userData': data
				},
				dataType: "html",
				beforeSend: function() {},
				success: function (response) {
					$('#hk-message')(response);
					if (response == 'success') {
						$("#hk-forgotpwd")[0].reset();
						$('#hk-message').hide();
						$('#hk-success').show();
					}
				}
			});
		});
	});
})(jQuery);
</script>

Xử lý dữ liệu trên server

Khi dữ liệu đã được gửi lên server thành công, chúng ta phải tiếp tục xử lý chúng. Bạn hãy thêm đoạn code dưới đây vào file functions.php nhé:

add_action('wp_ajax_nopriv_ForgotPassword', 'hk_handle_forgot_password');

function hk_handle_forgot_password() {
	$userData = [];

	if ( isset($_POST['userData']) && is_array($_POST['userData']) ) {
		$userData = $_POST['userData'];
	}

	if ( isset($userData['_wpnonce']) && wp_verify_nonce( $userData['_wpnonce'], 'form_forgot_password' ) ) {
		$arr_form = [];
		$arr_error = [];

		if ( isset( $userData['email'] ) && $userData['email'] ) {
			$arr_form['email'] = sanitize_text_field( $userData['email'] );

			if ( ! email_exists( $arr_form['email'] ) ) {
				$arr_error['email'] = 'Địa chỉ email chưa tồn tại trong hệ thống. Vui lòng kiểm tra lại';
			}
		} else {
			$arr_error['email'] = 'Bạn chưa nhập địa chỉ email';
		}

		if ( count( $arr_error ) ) {
			echo '<ul>';
			foreach ( $arr_error as $key => $error ) {
				echo '<li>'.$error.'</li>';
			}
			echo '</ul>';
		} else {
			$user = get_user_by( 'email', $arr_form['email'] );
			$user_id = $user->ID;
			$user_obj = new WP_User( $user_id );
			$reset_key = get_password_reset_key( $user_obj );
			$user_login = $user->user_login;
			$site_name = get_bloginfo( 'name' );

			$rp_link = network_site_url("wp-login.php?action=rp&key=$reset_key&login=" . rawurlencode($user_login), 'login');

			$to = $arr_form['email'];
			$subject = '['.$site_name.'] Yêu cầu thay đổi mật khẩu';
			$headers = array( 'Content-Type: text/html; charset=UTF-8' );

			$body = 'Yêu cầu thay đổi mật khẩu. <br/>';
			$body .= 'Nếu bạn đã yêu cầu đặt lại mật khẩu cho <strong>' . $user_login . '</strong>, hãy sử dụng đường dẫn bên dưới để đặt mật khẩu mới.<br/>Nếu không phải bạn thực hiện, vui lòng bỏ qua email này. <br/>';
			$body .= $rp_link;

			wp_mail( $to, $subject, $body, $headers );

			echo 'success';
		}
	}
	die();
}

Giải thích code cơ bản

Ở dòng 6, lúc này mình kiểm tra xem dữ liệu có được gửi lên server chưa. Nếu đã có dữ liệu gửi lên thì mình sẽ gán dữ liệu đó vào biến $userData.

Ở dòng 10, đây là bước xác minh nonce như mình đã đề cập ở bài trước. Nếu xác minh nonce thành công, chúng ta mới bắt đầu đi đến bước xử lý dữ liệu.

Ở dòng 17, mình sử dụng hàm email_exists để kiểm tra địa chỉ email có tồn tại chưa. Nếu chưa tồn tại thì hiển thị thông báo lỗi ra cho người dùng.

Ngoài ra, mình có sử dụng thêm hàm sanitize_text_field. Hàm này sẽ hỗ trợ bạn dọn dẹp chuỗi dữ liệu đầu vào của người dùng.

Giải thích code tạo URL đặt lại mật khẩu cho người dùng

Từ dòng 31 đến dòng 38 là đoạn code mình xử lý tạo một URL đặt lại mật khẩu cho người dùng.

Tại dòng 31, mình sử dụng hàm get_user_by để truy xuất thông tin người dùng. Hàm này nhận hai giá trị đầu vào là $field$value. Bạn có thể truy xuất thông tin người dùng với $fieldid, slug, email, login. Cụ thể trường hợp này mình sẽ sử dụng email. Còn $value là giá trị của $field, cụ thể ở đây là giá trị mà người dùng đã nhập vào form.

Sau đó mình sẽ gọi được đối tượng WP_User với ID người dùng đã lấy được tại dòng 32. Từ đây mình sử dụng hàm get_password_reset_key để nhận được key đặt lại mật khẩu.

Sau đó mình tạo được URL đặt lại cho người dùng và gán vào biến $rp_link.

Giải thích code gửi email cho người dùng

Từ dòng 40 đến dòng 48 là đoạn code mình xử lý để gởi email đến cho người dùng.

Mình sử dụng hàm wp_mail để gửi email. Hàm này nhận 5 giá trị đầu vào là $to, $subject, $message, $headers, $attachments.

  • $to: (string | string []) (Bắt buộc) Địa chỉ mail người nhận được phân tách bằng dấy phẩy hoặc mảng.
  • $subject(string) (Bắt buộc) Tiêu đề mail
  • $message: (string) (Bắt buộc) Nội dung mail
  • $headers: (string | string[]) (Không bắt buộc) Header bổ sung.
  • $attachments(string | string[]) (Không bắt buộc) Đường dẫn file đính kèm.

Ngoài ra để gửi email thành công, website của bạn phải cài đặt SMTP. Bạn có thể xem bài viết Hướng dẫn cài đặt SMTP gmail không cần sử dụng plugin nếu bạn chưa biết nhé.

Lời kết

Bản thân mình làm một dev thì mục tiêu bài viết này mình mong muốn các bạn hiểu rõ được tính năng khôi phục mật khẩu của WordPress. Đừng nên chỉ copy code mà không hiểu bản chất của nó. Từ đó các bạn có thể tha hồ xây dựng và tuỳ biến website theo đúng nhu cầu và sở thích của bản thân.

Nếu các bạn phát hiện ra sai sót của mình trong bài viết, hoặc góp ý thì comment ở bên dưới nha. Đây là phần 3 của series custom tài khoản wordpress, rất mong nhận được sự ủng hộ của các bạn để mình có động lực ra thêm các bài viết mới trong tương lai.

Đừng quên like Fanpage và subscribe kênh Youtube để ủng hộ mình nhé! Cảm ơn các bạn.