wordpress custom password reset page template

This tutorial will walk you through how to create a custom page template that will allow registered users to reset their password in case they forgot their current password.

After i wrote my tutorial named “Custom WordPress Login without using a plugin”, a lot of people asked me how to do the password reset in a custom way. But at that time i have not enough time to write and test it. So finally, i got some time to write this tutorial for you all.

This password reset will work in two steps. In the first step, we will create an activation key to reset the password and in the second step, we will validate the activation key and create a new password.

Create a new Page template

  1. <?php
  2. /*
  3. Template Name: Custom WordPress Password Reset
  4. */
  5. ?>

Create a new php file named password_reset.php or somename.php and put the above lines.

Overview of the Page Template

  1. <?php
  2. global $wpdb, $user_ID;
  3. wp_enqueue_script( 'jquery' );
  4.  
  5. if (!$user_ID) { //block logged in users
  6. //Validation stuffs, Form stuffs, etc
  7. }
  8. else {
  9. wp_redirect( home_url() ); exit;
  10. //redirect logged in users to home page
  11. }
  12. ?>

The above lines are same like what we did for the custom login and custom registration page templates in the
previous tutorials. Those lines are to redirect the logged in users to homepage.

Showing the password reset form

Put inside the if condition, if (!$user_ID) { }

  1. <div id="content">
  2. <h1><?php the_title(); ?></h1>
  3. <div id="result"></div> <!-- To hold validation results -->
  4. <form id="wp_pass_reset" action="" method="post">
  5.  
  6. <label>Username or E-mail</label><br />
  7. <input type="text" name="user_input" value="" /><br />
  8. <input type="hidden" name="action" value="tg_pwd_reset" />
  9. <input type="hidden" name="tg_pwd_nonce" value="<?php echo wp_create_nonce("tg_pwd_nonce"); ?>" />
  10. <input type="submit" id="submitbtn" name="submit" value="Reset" />
  11.  
  12. </form>
  13. <script type="text/javascript">
  14. jQuery("#wp_pass_reset").submit(function() {
  15. jQuery("#result").html("<span class='loading'>Validating...</span>").fadeIn();
  16. var input_data = jQuery("#wp_pass_reset").serialize();
  17. jQuery.ajax({
  18. type: "POST",
  19. url: "'. get_permalink( $post->ID ).'",
  20. data: input_data,
  21. success: function(msg){
  22. jQuery(".loading").remove();
  23. jQuery("<div>").html(msg).appendTo("div#result").hide().fadeIn("slow");
  24. }
  25. });
  26. return false;
  27. });
  28. </div>

So we are showing the password reset form only to users who are not logged in.

Get the permalink setting

  1. function tg_validate_url() {
  2. global $post;
  3. $page_url = esc_url(get_permalink( $post->ID ));
  4. $urlget = strpos($page_url, "?");
  5. if ($urlget === false) {
  6. $concate = "?";
  7. } else {
  8. $concate = "&";
  9. }
  10. return $page_url.$concate;
  11. }

The above function will help us to find the current permalink setting.

Validating the email and username

Now let’s write down the php validation part which will validate the email and username inputted by the user.

  1. if($_POST['action'] == "tg_pwd_reset"){
  2. if ( !wp_verify_nonce( $_POST['tg_pwd_nonce'], "tg_pwd_nonce")) {
  3. exit("No trick please");
  4. }
  5. if(empty($_POST['user_input'])) {
  6. echo'<span class="error">Please enter your Username or E-mail address</span>';
  7. exit();
  8. }
  9. //We shall SQL escape the input
  10. $user_input = $wpdb->escape(trim($_POST['user_input']));
  11.  
  12. if ( strpos($user_input, '@') ) {
  13. $user_data = get_user_by_email($user_input);
  14. if(empty($user_data) || $user_data->caps[administrator] == 1) {
  15. //the condition $user_data->caps[administrator] == 1 to prevent password change for admin users.
  16. //if you prefer to offer password change for admin users also, just delete that condition.
  17. echo'<span class="error">Invalid E-mail address!</span>';
  18. exit();
  19. }
  20. }
  21. else {
  22. $user_data = get_userdatabylogin($user_input);
  23. if(empty($user_data) || $user_data->caps[administrator] == 1) {
  24. //the condition $user_data->caps[administrator] == 1 to prevent password change for admin users.
  25. //if you prefer to offer password change for admin users also, just delete that condition.
  26. echo'<span class="error">Invalid Username!</span>';
  27. exit();
  28. }
  29. }
  30.  
  31. $user_login = $user_data->user_login;
  32. $user_email = $user_data->user_email;
  33.  
  34. $key = $wpdb->get_var($wpdb->prepare("SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $user_login));
  35. if(empty($key)) {
  36. //generate reset key
  37. $key = wp_generate_password(20, false);
  38. $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login));
  39. }
  40.  
  41. //emailing password change request details to the user
  42. $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n";
  43. $message .= get_option('siteurl') . "\r\n\r\n";
  44. $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
  45. $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n";
  46. $message .= __('To reset your password, visit the following address:') . "\r\n\r\n";
  47. $message .= tg_validate_url() . "action=reset_pwd&key=$key&login=" . rawurlencode($user_login) . "\r\n";
  48. if ( $message && !wp_mail($user_email, 'Password Reset Request', $message) ) {
  49. echo "<div class='error'>Email failed to send for some unknown reason.</div>";
  50. exit();
  51. }
  52. else echo '<div class='success'>We have just sent you an email with Password reset instructions.</div>';
  53.  
  54. }

You can see that i am generating an activation key and sending an email to the user with the activation key. The user need to follow the reset link in the email to reset the password.

Also, i had written a condition to prevent password change for admin users for security.

Validating activation key and Password reset

So now we need to validate the activation key and username from the reset link.

  1. if(isset($_GET['key']) && $_GET['action'] == "reset_pwd") {
  2. $reset_key = $_GET['key'];
  3. $user_login = $_GET['login'];
  4. $user_data = $wpdb->get_row($wpdb->prepare("SELECT ID, user_login, user_email FROM $wpdb->users WHERE user_activation_key = %s AND user_login = %s", $reset_key, $user_login));
  5. $user_login = $user_data->user_login;
  6. $user_email = $user_data->user_email;
  7. if(!empty($reset_key) && !empty($user_data)) {
  8. $new_password = wp_generate_password(7, false); //you can change the number 7 to whatever length needed for the new password
  9. wp_set_password( $new_password, $user_data->ID );
  10. //mailing the reset details to the user
  11. $message = __('Your new password for the account at:') . "\r\n\r\n";
  12. $message .= get_bloginfo('name') . "\r\n\r\n";
  13. $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";
  14. $message .= sprintf(__('Password: %s'), $new_password) . "\r\n\r\n";
  15. $message .= __('You can now login with your new password at: ') . get_option('siteurl')."/login" . "\r\n\r\n";
  16.  
  17. if ( $message && !wp_mail($user_email, 'Password Reset Request', $message) ) {
  18. echo "<div class='error'>Email failed to sent for some unknown reason</div>";
  19. exit();
  20. }
  21. else {
  22. $redirect_to = get_bloginfo('url')."/login?action=reset_success";
  23. wp_safe_redirect($redirect_to);
  24. exit();
  25. }
  26. }
  27. else exit('Not a Valid Key.');
  28.  
  29. }

The above process will generate a random 7 chanracter length password and send it to the user.

After sending the email, the page will be redirected to our custom login page, in which you can show some message like “You password has been changed. Now you can login with your new password”.

  1. //This goes in to your custom login page template
  2. if(isset($_GET['action']) && $_GET['action'] == "reset_success") {
  3. echo '<span class="success">You password has been changed. Now you can login with your new password</span>';
  4. }

Hope you like this tutorial. See you again with a new tutorial.

4,465 Downloads