We can implement WordPress AJAX Login and Register without a Plugin. This tutorial will assist to let you do it in right manner with some additional features too, including
Best practice techniques
Both forms in popup windows
AJAX Login and Register without a Plugin
Inbuilt client side form validation with jQuery
Opening login/register form from link given in another popup
I have written a post to add Forgot Password with AJAX functionality in code & steps mentioned here. Have a look over that tutorial too and download improved files there after reading this post.
So let’s do it right…
There’s a couple of ways to implement login or register on your website. You could create separate Pages called Login
and Register
and display the form on empty pages with page-login.php
and page-register.php
templates respectively (kind of what you have by default when visiting /wp-admin). Another is to keep the forms visible all the time above the header or in the sidebar. Third and the option we are using here is to call a login/register box when you click on a given button/link. Moreever you can easily apply the AJAX technique given here on any concept you want.
IMPORTANT: Please note that if you have already installed any other AJAX Login plugin then ensure to deactivate that first.
We have created the both forms in a separate file called ajax-auth.php
and called it for not logged in users using get_template_part()
function in WordPress. Create a file ajax-auth.php
inside your active theme’s directory and put the code given below in that.
<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"> <input class="submit_button" type="submit" value="SIGNUP"> <a class="close" href="">(close)</a> </form>
The wp_nonce_field
function creates a hidden field with ID “security” and value “ajax-login-nonce” in hashed form for login form. The same is acceptable for register form, a hidden field with ID “signonsecurity” and value “ajax-register-nonce”. We are using required
and email
classes to perform jQuery validation.
We also need login and signup buttons, so place that anywhere you want.
<?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 } ?>
This is the required CSS that you have to put inside a new file called ajax-auth-style.css
and place the file in css folder of your current theme.
form.ajax-auth{ dispay: none; z-index: 999; position: fixed; top: 150px; 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; } .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; }
Next part is the “login” and “signup” buttons show our form, validate and send the form data with AJAX to the function (which we will define in the next and last step).
We are using jquery.validate.js
for client side validation of forms and processing. Download this file from the link given at the end of this article and place this file inside your js folder of active theme.
Also Create a file called ajax-auth-script.js
and place it inside your js folder of active theme as well.
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(); if ($(this).attr('id') == 'register') { action = 'ajaxregister'; username = $('#signonname').val(); password = $('#signonpassword').val(); email = $('#email').val(); security = $('#signonsecurity').val(); } ctrl = $(this); $.ajax({ type: 'POST', dataType: 'json', url: ajax_auth_object.ajaxurl, data: { 'action': action, 'username': username, 'password': password, 'email': email, 'security': security }, success: function (data) { $('p.status', ctrl).text(data.message); if (data.loggedin == true) { document.location.href = ajax_auth_object.redirecturl; } } }); 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(); });
On the basis of data received we have to notify the user that login/registration was successful and perform the login or just notify him that his data is incorrect.
First I created a new folder libs
inside theme folder and then created file custom-ajax-auth.php
with all of these code below and saved file inside libs
folder. I will call this file in functions.php
for server side processing.
<?php function ajax_auth_init(){ 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' ); // 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(); }
Open functions.php file of your theme and place the line there:
require_once( get_template_directory() . '/libs/custom-ajax-auth.php' );
Function ajax_auth_init()
We have registered and enqueued necessary CSS and JS file here and created a JS object called ajax_auth_object
and enable the users with no privileges (not logged in) to call our functions as well.
The wp_ajax_nopriv_ajaxlogin
WordPress hook is important part to note. If you leave out “nopriv” and use wp_ajax_ajaxlogin
then only users that are logged in can access the functions.
Rest of the functions are self explanatory. They collect the data received from POST method, check if the nonce is valid and then tries to perform user register and/or login with the received data.
Congratulations! You have nice looking AJAX login and register forms now, powered with jQuery validation. You can perform WordPress AJAX Login and Register without a Plugin now.
Update (January 12, 2015): I have written a post to add Forgot Password with AJAX functionality in code & steps mentioned here. Have a look over that tutorial too and download improved files there after reading this post.
Included: ajax-auth-style.css, jquery.validate.js, ajax-auth-script.js, ajax-auth.php, custom-ajax-auth.php