Thanks to all visitors for their love to the article http://fellowtuts.com/wordpress/wordpress-ajax-login-and-register-without-a-plugin/. As we got many requests to implement Google reCaptcha in WordPress AJAX Register, I’m here with the wonderful code which will protect spams through Google reCaptcha during registration in your WordPress powered site.
The steps are same as previous article and again you can download zip at end of post and implement them. I would suggest you to read that post first because I’m focusing here just on what is running behind user reCaptcha validation.

Implementing Google reCaptcha in WordPress AJAX Register
To add reCaptcha validation, you must have Google site key and secret key. You can get it from here or you can follow the steps in this article to obtain keys.
The Form
Create a file ajax-auth.php
inside your active theme’s directory and put the code given below in that.
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 | <form id="login" class="ajax-auth" action="login" method="post"> <h3>New to site? <a id="pop_signup" href="">Create an Account</a></h3> <hr /> <h1>Login</h1> <p class="status"></p> <?php wp_nonce_field('ajax-login-nonce', 'security'); ?> <label for="username">Username</label> <input id="username" type="text" class="required" name="username"> <label for="password">Password</label> <input id="password" type="password" class="required" name="password"> <a class="text-link" href="<?php echo wp_lostpassword_url(); ?>">Lost password?</a> <input class="submit_button" type="submit" value="LOGIN"> <a class="close" href="">(close)</a> </form> <form id="register" class="ajax-auth" action="register" method="post"> <h3>Already have an account? <a id="pop_login" href="">Login</a></h3> <hr /> <h1>Signup</h1> <p class="status"></p> <?php wp_nonce_field('ajax-register-nonce', 'signonsecurity'); ?> <label for="signonname">Username</label> <input id="signonname" type="text" name="signonname" class="required"> <label for="email">Email</label> <input id="email" type="text" class="required email" name="email"> <label for="signonpassword">Password</label> <input id="signonpassword" type="password" class="required" name="signonpassword" > <label for="password2">Confirm Password</label> <input type="password" id="password2" class="required" name="password2"> <div class="g-recaptcha" data-sitekey="GOOGLE SITE KEY"></div> <!-- Replace your Google Site Key Above --> <input class="submit_button" type="submit" value="SIGNUP"> <a class="close" href="">(close)</a> </form> |
Here before submit button we placed a div to produce reCaptcha block in our registration form. The lines added as compared to previous article are highlighted. Don’t forget to place your site key at “GOOGLE SITE KEY“.
As now we need to show Login and Signup buttons somewhere in out site so place the code below in your theme file wherever you wish them to appear:
1 2 3 4 5 6 | <?php if (is_user_logged_in()) { ?> <a href="<?php echo wp_logout_url( home_url() ); ?>">Logout</a> <?php } else { get_template_part('ajax', 'auth'); ?> <a class="login_button" id="show_login" href="">Login</a> <a class="login_button" id="show_signup" href="">Signup</a> <?php } ?> |
CSS
Under your current theme’s css directory, you need to create a file called ajax-auth-style.css
with this code below. This is almost same as the CSS mentioned in previous article. Only changes are made highlight.
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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | form.ajax-auth{ display: none; z-index: 999; position: fixed; top: 100px; left: 50%; width: 350px; margin-left: -200px; padding: 40px 25px 25px 25px; background-color: #FFFFFF; border-radius: 8px; font-family: Arial, Helvetica, sans-serif; box-shadow: 0 0 6px rgba(0, 0, 0, 0.2); color: #878787; font-size: 11px; } .ajax-auth h1, .ajax-auth h3{ font-family: 'Georgia', 'Times New Roman', Times, serif; font-weight: 100; color: #333333; line-height: 1; } .ajax-auth h1{ font-size: 27px; text-align: center; margin: 0 0 20px 0; } .ajax-auth h3{ font-size: 18px; text-align: left; margin: 0; } .ajax-auth h3 a{ color: #e25c4c; } .ajax-auth hr { background-color: rgba(0, 0, 0, 0.1); border: 0 none; height: 1px; margin: 20px 0; } .ajax-auth input#username, .ajax-auth input#password, .ajax-auth input#signonname, .ajax-auth input#email, .ajax-auth input#signonpassword, .ajax-auth input#password2{ 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{ background-color: #FFF; } .ajax-auth label.error{ display: none !important; } .ajax-auth input.error{ border: 1px solid #FF0000 !important; } .ajax-auth input.submit_button{ font-size: 13px; color: #FFF; border: 1px solid #b34336; background-color: #e25c4c; border-radius: 3px; text-shadow: 0 1px 0 #ba3f31; padding: 9px 31px 9px 31px; background: -moz-linear-gradient(top, #ea6656, #df5949); border-top: 1px solid #bb483a; border-bottom: 1px solid #a63b2e; float: right; box-shadow: 0 1px 0 #E87A6E inset; margin-top: 20px; } .ajax-auth a{ text-decoration: none; } .ajax-auth a.close{ color: #DCDCDC; position: absolute; right: 15px; top: 15px; } .ajax-auth a.text-link{ color: #B4B2B2; float: left; margin: 10px 0 0 0; } .ajax-auth p.status{ text-align: center; margin: -15px 0 20px 0; font-weight: 600; display: none; } a.login_button{ font-family: Arial, Helvetica, sans-serif; padding: 5px 7px 5px 7px; background-color: #FFF; border-radius: 3px; border: 1px solid #DCDCDC; color: #333; text-decoration: none; font-size: 11px; } .login_overlay{ height: 100%; width: 100%; background-color: #F6F6F6; opacity: 0.9; position: fixed; z-index: 998; } |
Sending user info via AJAX
This is the tricky JS part which is required to let our recaptcha functionality work during registration and it’s also responsible for client side validation, sending AJAX request and process according to response received from server.
jquery.validate.js
and ajax-auth-script.js
, both are necessary to perform. Put both files in js folder in your active theme. The imprioved code for ajax-auth-script.js
is as follow:
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 | jQuery(document).ready(function($) { // Display form from link inside a popup $('#pop_login, #pop_signup').live('click', function(e) { formToFadeOut = $('form#register'); formtoFadeIn = $('form#login'); if ($(this).attr('id') == 'pop_signup') { formToFadeOut = $('form#login'); formtoFadeIn = $('form#register'); } formToFadeOut.fadeOut(500, function() { formtoFadeIn.fadeIn(); }) return false; }); // Close popup $(document).on('click', '.login_overlay, .close', function() { $('form#login, form#register').fadeOut(500, function() { $('.login_overlay').remove(); }); return false; }); // Show the login/signup popup on click $('#show_login, #show_signup').on('click', function(e) { $('body').prepend('<div class="login_overlay"></div>'); if ($(this).attr('id') == 'show_login') $('form#login').fadeIn(500); else $('form#register').fadeIn(500); e.preventDefault(); }); // Perform AJAX login/register on form submit $('form#login, form#register').on('submit', function(e) { if (!$(this).valid()) return false; $('p.status', this).show().text(ajax_auth_object.loadingmessage); action = 'ajaxlogin'; username = $('form#login #username').val(); password = $('form#login #password').val(); email = ''; security = $('form#login #security').val(); recaptcha = ''; ctrl = $(this).attr('id'); if (ctrl == 'register') { action = 'ajaxregister'; username = $('#signonname').val(); password = $('#signonpassword').val(); email = $('#email').val(); security = $('#signonsecurity').val(); recaptcha = $('#g-recaptcha-response').val(); } $.ajax({ type: 'POST', dataType: 'json', url: ajax_auth_object.ajaxurl, data: { 'action': action, 'username': username, 'password': password, 'email': email, 'security': security, 'recaptcha': recaptcha }, success: function(data) { $('p.status', ctrl).text(data.message); if (data.loggedin == true) document.location.href = ajax_auth_object.redirecturl; else if (ctrl == 'register') grecaptcha.reset(); } }); e.preventDefault(); }); // Client side form validation if (jQuery("#register").length) { jQuery("#register").validate({ rules: { password2: { equalTo: '#signonpassword' } } }); } else if (jQuery("#login").length) jQuery("#login").validate(); }); |
Here, two additional things are important to note. First, we are sending recaptcha variable with data object at form submission which is empty during login and filled by value of “g-recaptcha-response” field during registration. This field is being populated automatically by Google reCaptcha API script which we are going to add in our page just a moment later.
Second, based upon response from server, the reCaptcha is being reset if registration is failure as because you can’t submit the same recaptcha twice otherwise server will say “reCAPTCHA invalid” at next time.
Finally we need a regular login/signup server side handler along with some code to validate if reCaptcha is checked/filled & valid and process accordingly. The PHP script below does the rest of the task which is saved as custom-ajax-auth.php
inside libs folder in active theme.
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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | <?php function ajax_auth_init(){ wp_enqueue_script( 'google-reCaptcha', 'https://www.google.com/recaptcha/api.js' ); wp_register_style( 'ajax-auth-style', get_template_directory_uri() . '/css/ajax-auth-style.css' ); wp_enqueue_style('ajax-auth-style'); wp_register_script('validate-script', get_template_directory_uri() . '/js/jquery.validate.js', array('jquery') ); wp_enqueue_script('validate-script'); wp_register_script('ajax-auth-script', get_template_directory_uri() . '/js/ajax-auth-script.js', array('jquery') ); wp_enqueue_script('ajax-auth-script'); wp_localize_script( 'ajax-auth-script', 'ajax_auth_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'redirecturl' => home_url(), 'loadingmessage' => __('Sending user info, please wait...') )); // Enable the user with no privileges to run ajax_login() in AJAX add_action( 'wp_ajax_nopriv_ajaxlogin', 'ajax_login' ); // Enable the user with no privileges to run ajax_register() in AJAX add_action( 'wp_ajax_nopriv_ajaxregister', 'ajax_register' ); } // Execute the action only if the user isn't logged in if (!is_user_logged_in()) { add_action('init', 'ajax_auth_init'); } function ajax_login(){ // First check the nonce, if it fails the function will break check_ajax_referer( 'ajax-login-nonce', 'security' ); // Nonce is checked, get the POST data and sign user on // Call auth_user_login auth_user_login($_POST['username'], $_POST['password'], 'Login'); die(); } function ajax_register(){ // First check the nonce, if it fails the function will break check_ajax_referer( 'ajax-register-nonce', 'security' ); // Check if reCaptcha is valid $recaptcha=$_POST['recaptcha']; if(!empty($recaptcha)) { $google_url = "https://www.google.com/recaptcha/api/siteverify"; $secret = 'GOOGLE SECRET KEY'; // Replace your Google Secret Key here $ip = $_SERVER['REMOTE_ADDR']; $url = $google_url."?secret=".$secret."&response=".$recaptcha."&remoteip=".$ip; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_TIMEOUT, 10); curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16"); $results = curl_exec($curl); curl_close($curl); $res= json_decode($results, true); if(!$res['success']) { echo json_encode(array('loggedin'=>false, 'message'=>__('reCAPTCHA invalid'))); die(); } } else { echo json_encode(array('loggedin'=>false, 'message'=>__('Please enter reCAPTCHA'))); die(); } // Nonce is checked, get the POST data and sign user on $info = array(); $info['user_nicename'] = $info['nickname'] = $info['display_name'] = $info['first_name'] = $info['user_login'] = sanitize_user($_POST['username']) ; $info['user_pass'] = sanitize_text_field($_POST['password']); $info['user_email'] = sanitize_email( $_POST['email']); // Register the user $user_register = wp_insert_user( $info ); if ( is_wp_error($user_register) ){ $error = $user_register->get_error_codes() ; if(in_array('empty_user_login', $error)) echo json_encode(array('loggedin'=>false, 'message'=>__($user_register->get_error_message('empty_user_login')))); elseif(in_array('existing_user_login',$error)) echo json_encode(array('loggedin'=>false, 'message'=>__('This username is already registered.'))); elseif(in_array('existing_user_email',$error)) echo json_encode(array('loggedin'=>false, 'message'=>__('This email address is already registered.'))); } else { auth_user_login($info['nickname'], $info['user_pass'], 'Registration'); } die(); } function auth_user_login($user_login, $password, $login) { $info = array(); $info['user_login'] = $user_login; $info['user_password'] = $password; $info['remember'] = true; $user_signon = wp_signon( $info, false ); if ( is_wp_error($user_signon) ){ echo json_encode(array('loggedin'=>false, 'message'=>__('Wrong username or password.'))); } else { wp_set_current_user($user_signon->ID); echo json_encode(array('loggedin'=>true, 'message'=>__($login.' successful, redirecting...'))); } die(); } |
This is time to use your Google secret key and validate the reCaptcha response returned by user using curl. We used WordPress’s “wp_enqueue_script” function to add Google reCaptcha API script in our page, which shows a nice reCaptcha form above our signup submit button.
Inside “ajax_register” function there is code block to validate the reCaptcha entered by user with Google and successfully implementing Google reCaptcha in WordPress AJAX Register. Just not forget to replace “GOOGLE SECRET KEY” with your actual secret key you obtained from Google.
You can now perform a validation prior to registration if the user is a human and is not a robot with AJAX feature in WordPress AJAX login and register.
Download Zip
Included: ajax-auth-style.css, jquery.validate.js, ajax-auth-script.js, ajax-auth.php, custom-ajax-auth.php
I think this is among the most vital info for me. And i am glad reading your article. But should remark on some general things, The website style is perfect, the articles is really nice : D. Good job, cheers
I got this web page from my buddy who told me concerning this website and now this time I am browsing this site and reading very informative content at this place.
im stuck on register. Always: Please enter reCAPTCHA
I want use the recaptcha when logining. How ?
Hi @burakmeteerdoan:disqus
The steps are quite similar to the same implement for the Registration. The only glitch is you can’t use two Recaptcha on the same page (Login and Registration). I would suggest you to take some help of jQuery and shift wherever require.
Also, you need upgrading code for the client as well as the server. Please inspect what I have provided and try to do the same.
In case, you feel it difficult to implement, please write us to amit[at]astech[dot]solutions
im stuck on register. Always: Please enter reCAPTCHA
http://www.techindeep.com
hi Amit .. Thanks for the script and great explanation but some how its not working if in case there is some error like 1) email exists or 2) username exists etc
it just gets struck on Sending user info, please wait…”Sending user info, please wait…”
Hello @ojasyathakur:disqus
If you’re stuck at Sending user info then it means that the AJAX request isn’t being fired properly. Please check the request from developer console in the browser.
@amitsonkhiya:disqus Hi again. thanks for the prompt reply ..
I am not sure how to do that but I did try and check response in developer console > networks .. (http://tinyurl.com/yy6racqj)
I am getting response that “username already exists” . even captcha refreshes — its just that text “Sending user info, please wait…” never refreshes .. so confusing for a user .. ..
Looking forward for you reply
Hello @ojasyathakur:disqus
I’m doubtful that there is a little issue in the line #65 in ajax-auth-script.js here.
Can you replace
$('p.status', ctrl).text(data.message);
with
$('p.status').text(data.message);
and test again?
@amitsonkhiya:disqus
thanks for getting back..
Actually yeah I figured out that one as I looked the comments below and it worked perfect . now I again hit roadblock. when I change v2 captcha to V3
nowI am getting this — “ERROR for site owner: Invalid key type”..
will this not work with v3 or is there some other issue
hello Amit , thanks for your high quality tutorials . is there possible to integrate this ajax script with google sign in / sign up feature?! thank you .
Hello @Sultan Khan
It’s indeed possible to Integrate social login with AJAX script. However, you need having good technical knowledge to accomplish it including Google Sign In API, WordPress, PHP and jQuery.
Is it possible to add this reCAPTCHA to Reset Password form from your previous article about AJAX login/register?
Yes, it’s possible.
Do the same things as shown here, just in the code for Forget Password.
Additionally, move the server side validation code in the ajax_register() function (line no #48 to #74) to another function and call that new function in ajax_register() as well as ajax_forget() to validate the Recaptcha.
It’s clear, but we have such code
success: function(data) {
jQuery(‘p.status’, ctrl).text(data.message);
if (data.loggedin == true)
document.location.href = ajax_auth_object.redirecturl;
else if (ctrl == ‘register’)
grecaptcha.reset();
}
for registration form. How would we validate correct answer if in Forgot Password we have only
success: function(data) {
jQuery(‘p.status’, ctrl).text(data.message);
}
What should be the statement instead of ” if (data.loggedin == true) “. What to check?
It’s clear, but we have such code
success: function(data) {
jQuery(‘p.status’, ctrl).text(data.message);
if (data.loggedin == true)
document.location.href = ajax_auth_object.redirecturl;
else if (ctrl == ‘register’)
grecaptcha.reset();
}
for registration form. How would we validate correct answer if in Forgot Password we have only
success: function(data) {
jQuery(‘p.status’, ctrl).text(data.message);
}
What should be the statement instead of ” if (data.loggedin == true) “. What to check?
I haven’t tested code for multiple Recaptcha fields on the same page. You can use either separate Recaptcha fields and validate the used one or use the same field for both forms using JS.
Hope, these two articles could assist you to go in right direction. Still if any issue persists, don’t hesitate to revert.
http://mycodde.blogspot.com/2014/12/multiple-recaptcha-demo-same-page.html
https://stackoverflow.com/questions/1241947/how-do-i-show-multiple-recaptchas-on-a-single-page
Hi Amit,
Indeed a very nice piece of work. But unfortunately, I am unable to get this work for me. I have implemented exactly as described but upon clicking on sign up or login links, the background becomes Grey and nothing else happens. No pop up is displayed to register or login. Can you please guide me as what could be the cause of this issue? Issue image is attached below.
https://uploads.disquscdn.com/images/aeb100f125531af8e7c83936390220ced79a7ae244cfebebef910392ce0e06ff.jpg
Thanks.
Hi Athar,
Sorry as I couldn’t notice your comment. Is that issue resolved?
Hi Amit. No. Issue still exists.
Hi Athar. please share us link to the page where you are facing issue. You can write us to http://fellowtuts.com/contact/ if you wish to remain private or mail to support@fellowtuts.com
Hi Athar. please share us link to the page where you are facing issue. You can write us to here or at http://fellowtuts.com/contact/ if you wish to remain private or mail to support@fellowtuts.com
I had a probleme, the error message aren’t displaying. (i have the same probleme than
#comment-2469317715 ):
“. The reCaptcha is implemented with Register but the P.Status only shows Sending user info, please wait… when i tried to console it, the response was {“loggedin”:false, “message”:”Please enter reCaptcha”} but it doesn’t replaces on the P.Status div. ”
I have find a solution but i don’t know what was the probleme with “ctrl”
On the file: ajax-auth-script.js
I change this line (65)
$(‘p.status’, ctrl).text(data.message);
with this
$(‘p.status’).text(data.message);
And now it’s work.
@Zeckart thank you for sharing and glad you solved it. I will recheck the issue at later time as it’s not appearing in my browser.
Hi Amit,
Thanks for great tutorial. Do you consider extending it with description on how to add verifying email with confirmation link? That would be awesome! 😉
Hi Dawid,
We have added this subject to list of posts to write about. We will sure describe it whenever would have time.
If you need immediate requirement, you can write us to support@fellowtuts.com
Hi Amit,
I have implemented this updates with your all updates in one i.e. login, register and forgot password on the page rather than popup. The reCaptcha is implemented with Register but the P.Status only shows Sending user info, please wait… when i tried to console it, the response was {“loggedin”:false, “message”:”Please enter reCaptcha”} but it doesn’t replaces on the P.Status div. And once i am able to logged in, it still doesn’t show Successful, Redirecting….
Something tiny thing is missing. Please help
Hi,
I think that the code inside success callback of js script is not firing. Please look at there carefully again and still if you are unable to fix, you can drop us an email with url to check at support@fellowtuts.com
Thanks
Hi Amit,
I have implemented your code however it doesn’t work fine for me. When I try to register without confirming captcha I am getting error “Please enter reCAPTCHA” as expected. But when I click on captcha checkbox, google verifies my identity but I am still getting the same error. Do you have any clue where should I look for?
I checked my site using firebug and what I found is that g-recaptcha-response doesn’t get any value after sumbiting and thats probably why validation is failing…
Actually I found that isn’t an issue. I am alerting out field value:
recaptcha = $(‘#g-recaptcha-response’).val();
alert(recaptcha);
And I can see that it has some content (random string of carachters) so for some reason PHP part doesn’t recognize it…
I found the issue, I was adjusting existing code from previous tutorial, so I changed all highlighted parts, however in ajax-auth-script.js line 61 isn’t highlighted therefore I missed it: (‘recaptcha’: recaptcha)
Dawid,
Thanks for drawing my attention. I have highlighted it now.
Thank you
Hi, i did every thing as you, but it doesn’t validate the recaptcha. it just ignores recaptcha and logs in.
You should try to first echo any message inside ajax_register function to check if it’s producing any output
Hi Amit, it worked perfect. thank you. just one question. how is it possible to implement recaptcha just for login?
Do the same on login as we did for register by inspecting the code in this article carefully.If you find it difficult to implement then you can write us here: http://fellowtuts.com/troubleshooting/
Hi, I have implement is accurately. It is nice, but it doesn’t work on my site. When I click on I’m not roboot, recaptacha popup and invalided and then when I click on register, it returns enter recaptcha. help plz.
Have you registered the site for google recaptcha? If you are trying on local it won’t work.