How to Create WordPress custom AJAX login/registration form?

A few days ago, I was building a multi-user application for a client. The WordPress admin panel has been completely avoided in the application. Since a custom dashboard has been created, it was very important to create a custom login/registration UI to match the dashboard.

I used to do this with a post request on the login/registration page. But the default login/registration pages have been restricted in this application. So, I created a function for form handling and authorized it in WP_AJAX.

Let me share how you can create this ajax login/registration system for your WordPress application.

You can follow these steps to develop a custom login and registration form on a WordPress site using AJAX for multi-user applications.

AJAX Call Authorization

At first, I have authorized Ajax calls with this function in the theme.

function ajax_auth_init(){	

    wp_register_script('validate-script', plugin_dir_path( __FILE__ ) . 'assets/js/jquery.validate.js', array('jquery') ); 
    wp_enqueue_script('validate-script');

    wp_register_script('ajax-auth-script', plugin_dir_path( __FILE__ ) . 'assets/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...')
    ));

    add_action( 'wp_ajax_nopriv_ajaxlogin', 'ajax_login' );
    add_action( 'wp_ajax_nopriv_ajaxregister', 'ajax_register' );

}

The ajax_auth_init() function simply authorizes the ajax_login() and ajax_register() functions to be executed via Ajax. And the form validation script has also been incubated from here.

Now you need to initiate the ajax_auth_init() function. Since this is a login/registration form, I will initiate it only for non-logged-in visitors.

if (!is_user_logged_in()) {
    add_action('init', 'ajax_auth_init');
}

Ajax Authorization, Initiative, and Validation Skip Inquiry are over. Now let’s move on to front-end form setup.

Login system

Let’s start with the login. For complete login setup, we need to setup login form, login function (ajax_login), and ajax call.

Login form

Here is the Naked HTML form. You can make the markup as you wish.

<form id="loginform" role="form" method="post">
    <input class="form-control" id="userloginemail" placeholder="Email" type="text" name="log" required>
    <input id="userloginpwd" class="form-control" placeholder="Password" type="password" name="pwd">
    <?php wp_nonce_field( 'ajax-login-nonce', 'security' ); ?>
    <button id="loginformsubmit" type="submit" class="btn btn-primary my-4">SIGN IN</button>
    <p id="loginformerror"></p>
</form>

Make sure wp_nonce_field is not missing; this is a must-have, for any Affiliate, promoting any program.

Login function

In the authorization function, we made ajax_login() executable from Ajax; now, I will write the function. Security checking, error handling, and final login, everything will be from this function.

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
    $info = array();
    $info['user_login'] = $_POST['username'];
    $info['user_password'] = $_POST['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 {
        echo json_encode( array( 'loggedin'=>true, 'message'=>__('Login successful, redirecting...' )));
    }

    die();

}

If the Posted username and password are correct, it will log in the user and return a logged-in message to Ajax Response, which we will check and initiate a front-end redirect. If there is any error, it will return to Ajax Response, and we will show it at the front-end.

AJAX call

The last step of the login system is to handle Ajax calls and returned data.

$("#loginform").submit(function(e) {

    e.preventDefault();

    var form = $(this);
    $("#loginformsubmit").text("Signing In...");
    $("#loginformerror").html('');

    $.ajax({
        type: 'POST',
        dataType: 'json',
        url: ajax_auth_object.ajaxurl,
        data: { 
            'action': 'ajaxlogin', //calls wp_ajax_nopriv_ajaxlogin
            'username': $('#userloginemail').val(), 
            'password': $('#userloginpwd').val(), 
            'security': $('#security').val() 
        },

        success: function(data){
            $("#loginformsubmit").text("Sign In");
            if (data.loggedin == true){
                $("#loginformerror").html(data.message);
                $("#loginformsubmit").text("Redirecting...");
                document.location.href = "<?php echo home_url('/');?>";
            } else {
                $("#loginformerror").html(data.message);
            }
        }
    });

});

Note: JQuery has been used here, so the code must be executed after the JQuery is loaded.

Here the username and password from the form are sent to the ajax_login() function via wp_ajax. If the data returned after processing the data in the function shows that everything is OK and logged in, it will redirect the user to the homepage. And if there is an error (such as, wrong password), it will show in the form.

Registration system

Almost the same process in the registration system. Auto-login function as form, ajax call, registration function, and extra.

Registration Form

A naked HTML form is given here like login form, you can arrange it as per your requirement.

<form id="userregisterform" role="form" action="/wp-login.php" method="post">
    <input class="form-control" placeholder="First Name" type="text" name="fname" id="userfname">
    <input class="form-control" placeholder="Last Name" type="text" name="lname" id="userlname">
    <input class="form-control" placeholder="Email" type="text" name="email" id="useremail">
    <input class="form-control" placeholder="Password" type="password" name="pwd" id="userpwd">
    <?php wp_nonce_field('ajax-register-nonce', 'signonsecurity'); ?>  
    <button id="registerformsubmit" type="submit" class="btn btn-primary my-4">REGISTER</button>
    <div id="loginformerror"></div>
 </form>

Here again, the wp_nonce_field field is required to ensure security.

Registration function

To process the Ajax call, you need to type the ajax_register() function, which we first made Ajax executable.

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'] = sanitize_text_field( $_POST['fname']);
    $info['nickname'] = sanitize_text_field( $_POST['fname']);
    $info['first_name'] = sanitize_text_field( $_POST['fname']);
    $info['last_name'] = sanitize_text_field( $_POST['lname']);
    $info['user_login'] = sanitize_email( $_POST['email']);
    $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['user_login'], $info['user_pass'], 'Registration');       

    }

    die();

}

The function will check all the data that posted, and if any error is found, it will return, and it will check the returned data and show the error in the form.

And if all goes well, the user will create and call the auto login function (auth_user_login) to auto login the user. If you do not want auto-login, you can return user creation successful data without calling auto-login function. In that case, you also need to customize the Ajax return data handling. Here I am proceeding with auto login.

Auto login function

ajax_register() After the user registration is successful; the new user needs to enter the auth_user_login() function to be able to login automatically.

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, '' ); // From false to '' since v4.9

    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();

}

There is no possibility of error here because the user has been created with the data; the login is also being done with the same data. Even then, error checking has been kept to be over sure.

If no error is found, it will make the user login and return the same message as the login successful message is being returned in the login function.

AJAX call

All the back-end functionality of the registration form is over; now, it’s time to touch the front-end and call Ajax.

$("#userregisterform").submit(function(e) {
    e.preventDefault();

    var form = $(this);
    var url = form.attr('action');
    $("#registerformsubmit").text("Signing In...");
    $("#loginformerror").html('');
    email = $('#useremail').val(), 
    fname = $('#userfname').val(), 
    lname = $('#userlname').val(), 
    password = $('#userpwd').val(), 
    security = $('#signonsecurity').val()

    $.ajax({

        type: 'POST',
        dataType: 'json',
        url: ajax_auth_object.ajaxurl,
        data: { 
            'action': 'ajaxregister', //calls wp_ajax_nopriv_ajaxlogin
            'email': email, 
            'fname': fname, 
            'lname': lname, 
            'password': password, 
            'security': security
        },

        success: function(data){
            $("#registerformsubmit").text("Register");
            if (data.loggedin == true){
                $("#loginformerror").html(data.message);
                $("#registerformsubmit").text("Redirecting...");
                document.location.href = "<?php echo home_url('/');?>";
            } else {
                $("#loginformerror").html(data.message);
            }
        }

    });
});

Similar to the login form, here, the user data from the form is sent to ajax_register() for processing. If ajax_register() returns an error (such as the user already exists), the form will show an error. And if all goes well and the login returns via auth_user_login(), it will redirect the user to the homepage by showing a success message.

I have tried to explain it simply. If there is any problem in understanding, the comment section below is open 24 hours.