After getting many requests from visitors to integrate Forgot Password with AJAX in my previous article WordPress AJAX Login and Register without a Plugin I decided to write a post about steps and code to add in that article to include Forgot Password functionality. This article is an improvement over that previous article as well as it will be sure helpful to understand how does the functionality actually work.
Forgot Password with AJAX in WordPress
The form opens as popup when you click ‘Lost password‘ link given inside ‘Login‘ popup and send an email to validated user after setting new password in WordPress database. You can download the complete zip of files at the end of this post to add in your theme to implement AJAX Login, Register and Forgot Password without a plugin and powered with jQuery client side validation.
The Form
Starting from ajax-auth.php
file we have added a form there to obtain input by user.
1 2 3 4 5 6 7 8 9 | <form id="forgot_password" class="ajax-auth" action="forgot_password" method="post"> <h1>Forgot Password</h1> <p class="status"></p> <?php wp_nonce_field('ajax-forgot-nonce', 'forgotsecurity'); ?> <label for="user_login">Username or E-mail</label> <input id="user_login" type="text" class="required" name="user_login"> <input class="submit_button" type="submit" value="SUBMIT"> <a class="close" href="">(close)</a> </form> |
CSS
To style the input textbox and submit button, we are adding .ajax-auth input#user_login
and .ajax-auth input#user_login:focus
classes after line numbers 53 and 71 respectively in ajax-auth-style.css
and code are highlighted below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | .ajax-auth input#username, .ajax-auth input#password, .ajax-auth input#signonname, .ajax-auth input#email, .ajax-auth input#signonpassword, .ajax-auth input#password2, .ajax-auth input#user_login{ border: 1px solid #EDEDED; border-radius: 3px 3px 3px 3px; box-shadow: 0 0 3px rgba(0, 0, 0, 0.1) inset; color: #333333; font-size: 15px; padding: 10px 10px 10px 13px; width: 325px; margin: 7px 0 20px 0; background-color: #F9F9F9; font-family: 'Georgia', 'Times New Roman', Times, serif; } .ajax-auth input#username:focus, .ajax-auth input#password:focus, .ajax-auth input#signonname:focus, .ajax-auth input#email:focus, .ajax-auth input#signonpassword:focus, .ajax-auth input#password2:focus, .ajax-auth input#user_login:focus{ background-color: #FFF; } |
Script
The script part handles showing the form, validates the textbox, sends information inputted by user to server and notifies user as per the response received through AJAX. Methods added into ajax-auth-script.js
are
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // Display lost password form $('#pop_forgot').click(function(){ formToFadeOut = $('form#login'); formtoFadeIn = $('form#forgot_password'); formToFadeOut.fadeOut(500, function () { formtoFadeIn.fadeIn(); }) return false; }); // Perform AJAX forget password on form submit $('form#forgot_password').on('submit', function(e){ if (!$(this).valid()) return false; $('p.status', this).show().text(ajax_auth_object.loadingmessage); ctrl = $(this); $.ajax({ type: 'POST', dataType: 'json', url: ajax_auth_object.ajaxurl, data: { 'action': 'ajaxforgotpassword', 'user_login': $('#user_login').val(), 'security': $('#forgotsecurity').val(), }, success: function(data){ $('p.status',ctrl).text(data.message); } }); e.preventDefault(); return false; }); // Client side form validation if(jQuery('#forgot_password').length) jQuery('#forgot_password').validate(); |
Handling the AJAX Request
In custom-ajax-auth.php
that does all server side processing, we have added just one line as WordPress action hook to call ajax_forgotPassword()
as well as the function itself. So the modified code is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | function ajax_auth_init(){ ... // Enable the user with no privileges to run ajax_forgotPassword() in AJAX add_action( 'wp_ajax_nopriv_ajaxforgotpassword', 'ajax_forgotPassword' ); } function ajax_forgotPassword(){ // First check the nonce, if it fails the function will break check_ajax_referer( 'ajax-forgot-nonce', 'security' ); global $wpdb; $account = $_POST['user_login']; if( empty( $account ) ) { $error = 'Enter an username or e-mail address.'; } else { if(is_email( $account )) { if( email_exists($account) ) $get_by = 'email'; else $error = 'There is no user registered with that email address.'; } else if (validate_username( $account )) { if( username_exists($account) ) $get_by = 'login'; else $error = 'There is no user registered with that username.'; } else $error = 'Invalid username or e-mail address.'; } if(empty ($error)) { // lets generate our new password //$random_password = wp_generate_password( 12, false ); $random_password = wp_generate_password(); // Get user data by field and data, fields are id, slug, email and login $user = get_user_by( $get_by, $account ); $update_user = wp_update_user( array ( 'ID' => $user->ID, 'user_pass' => $random_password ) ); // if update user return true then lets send user an email containing the new password if( $update_user ) { $from = 'WRITE SENDER EMAIL ADDRESS HERE'; // Set whatever you want like mail@yourdomain.com if(!(isset($from) && is_email($from))) { $sitename = strtolower( $_SERVER['SERVER_NAME'] ); if ( substr( $sitename, 0, 4 ) == 'www.' ) { $sitename = substr( $sitename, 4 ); } $from = 'admin@'.$sitename; } $to = $user->user_email; $subject = 'Your new password'; $sender = 'From: '.get_option('name').' <'.$from.'>' . "\r\n"; $message = 'Your new password is: '.$random_password; $headers[] = 'MIME-Version: 1.0' . "\r\n"; $headers[] = 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; $headers[] = "X-Mailer: PHP \r\n"; $headers[] = $sender; $mail = wp_mail( $to, $subject, $message, $headers ); if( $mail ) $success = 'Check your email address for you new password.'; else $error = 'System is unable to send you mail containg your new password.'; } else { $error = 'Oops! Something went wrong while updaing your account.'; } } if( ! empty( $error ) ) echo json_encode(array('loggedin'=>false, 'message'=>__($error))); if( ! empty( $success ) ) echo json_encode(array('loggedin'=>false, 'message'=>__($success))); die(); } |
The code block is self explanatory and we have used a number of WordPress inbuilt functions here as defined in global wbdb class. We are trying to match user input with an existing user in database through email first and then username (if input is not an email) as well as added error in case of empty/invalidated or non-existing user.
If a user matches then we tried to assign it a new password, update the database table and attempted to send new password to the user.
NOTE: Please provide a valid email address for sender field ($from at line number 8) otherwise system will use ‘admin@yoursite.com’ as default sender (yoursite.com will get replace with your domain name).
It’s all about embedding Forgot Password functionality in AJAX Login and Register without a Plugin in WordPress.
Download Zip
Included: ajax-auth-style.css, jquery.validate.js, ajax-auth-script.js, ajax-auth.php, custom-ajax-auth.php (updated for Forgot Password with AJAX)
Or if you are intended to just use login and register without a plugin then please refer to this tutorial.
Greetings, Amit!
I have a big request for you – help implement the function of sending a message to the mail of registered WordPress users about the release of a new blog article.
I used to use the subscribe 2.10.37 plugin, but recently it doesn’t work for me and gives errors. The blog is slow.
I searched the web for a function without a plugin, but I couldn’t find it. I don’t have the experience to do it myself.
Hello Amit,
Thanks for this great tutorial. I added .success and .fail classes to the .status element of the Login and Register forms like this:
[...]
success: function (data) {
$('p.status', ctrl).text(data.message);
if (data.loggedin == true) {
$('form#login p.status, form#register p.status').addClass('success');
document.location.href = ajax_auth_object.redirecturl;
} else {
$('form#login p.status, form#register p.status').addClass('fail');
}
}
[...]
How to do the same for the Forgot Password form?
Thanks!
Yoann
Hi,
This tutorial seems to be obsolete.
In the AJAX call, the string action parameter ‘ajaxforgotpassword’ seems to be false or no-updated. In the admin-ajax.php, this action paramater is not present.
Could you fix issues and mistales in this tutorial ?
Hi Mehdi
The script is correct. Please check how the wp_ajax_nopriv_* hook works using the link:
https://developer.wordpress.org/reference/hooks/wp_ajax_nopriv_action/
There may be some issue with your implementation
Cool blog! Is your theme custom made or did you download it from somewhere? A theme like yours with a few simple adjustements would really make my blog shine. Please let me know where you got your theme. Thanks
Hi,
This is a custom made theme with using Bootstrap 4.
Very nice post. I just stumbled upon your weblog and wanted to say that I’ve really enjoyed browsing your blog posts. After all I will be subscribing to your feed and I hope you write again soon!
Hey! Would you mind if I share your blog with my facebook group? There’s a lot of people that I think would really enjoy your content. Please let me know. Many thanks
Hi,
Sharing is caring, you’re most welcome to share.
You really make it appear really easy with your presentation but I find this matter to be actually something which I think I would never understand. It kind of feels too complex and very extensive for me. I am looking ahead to your next put up, I’ll try to get the grasp of it!
Hello! I could have sworn I’ve been to this site before but after looking at many of the posts I realized it’s new to me. Anyhow, I’m certainly pleased I stumbled upon it and I’ll be bookmarking it and checking back frequently!
thanks for your code which was working like charm..
U just rox saved me quite a couple of hours 😉
Also it could be nice to make the password expirable or send a link that goes into a new password page creation instead of receiving the password.
Dunno what is safer. Any ideas?
@juliendavidb:disqus
Sending the password reset link is always better. However, most of the users feel comfort to keep code easy and understandable. You can replace the the code in ajax_forgotPassword() function to send the reset link. The SO answer might help you:
https://wordpress.stackexchange.com/questions/60318/sending-the-reset-password-link-programatically
We would be also happy to implement that for you. Just write me at amit@astech.solutions or use the link:
https://www.astech.solutions/services/wordpress-development-themes-plugins/
How to show other fields during user registration like nickname display name or first name?
how to change Forgotten Password reset function to send a link to reset password instead send new password via email ?
hii amit , after clicking forgot password it send two mail ..how can i remove one mail
Hi @disqus_i4vcRJRgdC:disqus
The function responsible to send email is being called twice. Check your server side code carefully & correct it.
Alternatively, it you’re using some other code/plugin to perform the same, that might also cause the issue.
hii amit,
i need a help , in your code , a random password is sending to mail.but i need change my password .how can i do that
Hi you can change it later through url
yourdomain.com/wp-admin/profile.php
An interesting discussion is definitely worth comment. There’s no doubt that that you need to write more on this topic, it might not be a taboo matter but generally people don’t talk about such topics. To the next! Kind regards!!
System is unable to send you mail containg your new password. what i can do for that
Hi,
You can tell user to retry in a few minutes in response
ya i tried that but after few minutes i get only a blank msg from that ,it not contain any link for passsword updation
Hi
I think you need to change content type to texthtml from plain. Refer the article: https://developer.wordpress.org/reference/functions/wp_mail/
Hi Amit,
i am using WPLMS theme and i want onclick image login and registration form will come in popups and when user register ,automatically user logged in and redirect to same page .
i have download your code but i don’t know how to use in wordpress.
Can you help me ?
Please send us link to url of page where you want to implement this feature to support@fellowtuts.com
Hello! I found a small error in your script, which also relates to the question by Gregory Mathews about it forcing re-login for admin section.
You use wp_set_current user, to log in. According to the codex, this is not enough to log a user in, and you must also:
wp_set_auth_cookie( $user_id );
do_action( ‘wp_login’, $user->user_login );
https://codex.wordpress.org/Function_Reference/wp_set_current_user#Examples
My whole else block is as follows, in the custom-ajax-auth.php file:
else {
$user = get_user_by( ‘id’, $user_signon->ID);
wp_set_current_user($user_signon->ID, $user->user_login);
wp_set_auth_cookie( $user_signon->ID );
do_action( ‘wp_login’, $user->user_login );
echo json_encode(array(‘loggedin’=>true, ‘message’=>__($login.’ successful, redirecting…’)));
}
Thank you!
Hi Dan
Thank you for the update. We will review & update in the weekend.
You’re welcome! What did you think of the change?
@dandulaney:disqus
I missed to reply you here. We’re using wp_signon() functions before setting the current user which already does what you expressed. Please check line #100 in the link below.
Ref.: https://developer.wordpress.org/reference/functions/wp_signon/#source
I keep getting “Cannot create a user with an empty login name.” when trying to use the register feature. Any suggestions? I’ve plugged the code in exactly as it is downloaded.
Hi knolaust
It seems that POST parameters are not passing to server correctly. Can you check what are being passed from browser using firebug and what is received at server using var_dump($_POST);
Nothing. It’s passing the security and that’s it. Here’s the form for register (note: login and forgot password work). I may have stared at this so long that I’m missing something obvious.
Become a Member
First, let’s setup a username and password. Then you can complete the application.
Username
Email
Password
Confirm Password
Already have an account? Login
Great tutorial man! We’ve just used it on our website.
Thank you for the working tutorial.
Is there a way to allow users to set their new password what they want within the forgot password section instead of giving them generated password please?
Thanks in advance.
You have an error in your files, in cusom-ajax-auth.php you check_ajax_referer in all three ways with parameter “security”, but it must be “security”, “signonsecurity” and “forgotsecurity”
Quick question (awesome work BTW): if I successfully login using my ADMIN CREDS, then attempt to navigate to the WP ADMIN area, I am redirected to the default WP Login page and logged out of my current session. Is this a security thing with WP in the way the Custom WP AJAX Login works? Thanks again for contributing to the community.
Hi Gregory
There is no such default implementation by WordPress. I suggest you to review plugins you have installed in your site, they might cause the issue.
Thanks for your kind words.
Hi Amit,
What if we wanted to use the Password Reset via link option (like WP does by default) in lieu of generating one on the user’s behalf and emailing them the result? Can that be accomplished via your code as well? This would help prevent “unauthorized” password resets as the user would have to click the link in the email to actually choose and reset their password.
G.
Hi Greogory,
You can indeed accomplish so and it needs modifications in register function at server side script. I you would need one, you can write us at support@fellowtuts.com
Gregory, see my post up top for a solution to this.
Hai , Forget Password options worked in Localhost server,, i want more detailed explaination
Hi, I have been playing woth your script for a site of my own and found that It lets you register even if you put to different passwords in the form.
And just something that happens to me is that I can’t recover the password as it says “System is unable to send you mail containg your new password.” I am trying it in localhost, might that be the reason?
Regards and thanks!
Different password with? What about Username?
Yes your mailserver at localhost is not configured that’s why you are getting the message. It will work fine on live.
I mean that if in the register form you type two different valuesfor the password and confirm password field, the form is submitted anyway.
Whoop! I forgot to add that validation before form submission. Thank you and I will implement that very soon.
Great, many thanks!
I have been trying to fix it but it exceeds my knoledge apparently… tryied many ways and couldn’t.
Anyway, I will be waiting!
Thanks again
Hi,
I have updated the code. A jQuery implementation has been made at end in ajax-auth-script.js. Download the updated files.
Thanks.
Hi Amit!
I downloaded it, tryied it but the error persists 😛
Can you give me url of page where you have implemented the code.
Hi,
I have added the forgot password script.
But when I click “forgot password ?” in login form, it goes to default forgot page “wp-login.php?action=lostpassword”
Thanks!
Hi,
I read you comment and understand the code. There you have remove href attribute’s value. Is your issue resolved now?
yes, I resolved !