Last week I was building a multi-user application for a client. That application needed a custom dashboard for users. It was not a requirement, but I wanted to avoid WordPress core login and registration page to match the custom dashboard UI.

It is easy to simply POST login/registration data to the WordPress core login/registration page. but, I wanted to hide the core login/registration page completely. so, I created an authorization function to do the login/registration process through Ajax.

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

Enable AJAX authorization:

At first, we need an authorization function to enable ajax.

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 in functions.php enabled the user to run ajax_login() and ajax_register() via Ajax without any privileges.

Call this function only if the user, not logged-in.

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

Login System:

Ajax authorization is done. now we need to create login form and login function.

Login Form:
Here is a naked login form. please use your HTML.

<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 you added wp_nonce_field for ensuring the security of your login page.

Login Function:
Now let's create a login function in functions.php to process the login and return status.

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

}

ajax_login() function will check the info you sent via ajax. If information correct, it will let the user logged-in and return a success message. If the information is wrong, it will return an error message.

Ajax Call:
Now we are in the final step of the login system.

$("#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);
            }
        }
    });

});

Make sure jQuery is loaded before this JavaScript code. By the code above we collect the value from input fields and send them to ajax_login() function. if there is any error, it will show the error in the form. if login successful user will be redirected to the homepage.

Registration System

Now let's create the WordPress user registration system with ajax.

Registration Form:
Here is a naked HTML form for registration.

<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>

Use your CLASS NAME and markup for styling. Make sure you added wp_nonce_field for ensuring security.

Registration Function:
Add this function in functions.php to process user registration.

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

}

ajax_register() function will collect registration data from POST and create user account. If there is any error like email exists, blank field, etc. it will return an error message.

If everything okay, It will create the user account and log in to the new account using the auth_user_login() function. Add this auth_user_login function in functions.php to enable auto-login.

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

}

Ajax Call:
Now let's call the registration function from front-end.

$("#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);
            }
        }

    });
});

This JavaScript will POST the registration form data to ajax_register() function. If the function returns any error it will show the error and if successfully logged-in using auth_user_login(), it will redirect the user to the homepage.

Please let me know if you have any questions or difficulties in the comment section.