A Step-by-Step Tutorial for Custom Login and Register in WordPress with AJAX

Introduction

Are you Curious about how to create a custom login and register form in WordPress without any plugin? Not everyone wants to install a plugin on their WordPress website for every little things. Especially when you just need a simple registration and login form for your site users.

Fortunately, WordPress comes with some functions. It’s quite easy to create a simple user registration and login form in WordPress with the default WordPress functions and you don’t need any type of plugins.

In this tutorial, I will demonstrate how you can create a custom login and register page in WordPress using the function in a custom page template.

Prerequisites

Before we begin, make sure you have:

  1. Access to your WordPress site’s files via FTP or a file manager.
  2. Basic knowledge of HTML, CSS, and PHP.

Step 1: Create Custom Login and Register Forms

1.1 Create a Custom Login Form
Create a new file named custom-login.php in your theme directory. Add the following code:

<?php
/*
Template Name: Custom Login
*/

// If user is already loggedin then redirect him/her to my-account page
if(is_user_logged_in()) {
    wp_redirect( site_url('my-account') );
}

get_header();
?>
<form class="login-form" id="login-form" action="" method="post">
    <div class="form-row">
        <label for="user_email">Email</label>
        <input type="email" name="user_email" id="user_email" class="form-control" required="required"/>
    </div>
    <div class="form-row">
    	<label for="user_password">Password</label>
    	<input type="password" name="user_password" id="user_password" class="form-control" required="required" />
    </div>
    <?php wp_nonce_field('login_user_nonce', 'login_user_nonce'); ?>
    <button type="submit" class="btn btn-primary submit-btn">Sign in</button>
</form>
<?php
get_footer();
?>

Implement your custom login form and include the necessary JavaScript for AJAX functionality.

1.2 Create a Custom Register Form
Similarly, create a file named custom-register.php with a template structure like the one above. Implement your custom registration form and include the necessary JavaScript.

<?php
/*
Template Name: Custom Register
*/

// If user is already loggedin then redirect him/her to my-account page
if(is_user_logged_in()) {
    wp_redirect( site_url('my-account') );
}

get_header();
?>
<form class="register-form" id="register-form" action="" method="post">
    <div class="form-row">
        <label for="user_first_name">First Name</label>
        <input type="text" name="user_first_name" id="user_first_name" class="form-control" required="required"/>
    </div>
    <div class="form-row">
        <label for="user_last_name">Last Name</label>
        <input type="text" name="user_last_name" id="user_last_name" class="form-control" required="required"/>
    </div>
    <div class="form-row">
        <label for="user_email">Email</label>
        <input type="email" name="user_email" id="user_email" class="form-control" required="required"/>
    </div>
    <div class="form-row">
    	<label for="user_password">Password</label>
    	<input type="password" name="user_password" id="user_password" class="form-control" required="required" />
    </div>
    <div class="form-row">
    	<label for="user_cpassword">Confirm Password</label>
    	<input type="password" name="user_cpassword" id="user_cpassword" class="form-control" required="required" />
    </div>
    <?php wp_nonce_field('register_user_nonce', 'register_user_nonce'); ?>
    <button type="submit" class="btn btn-primary submit-btn">Sign up</button>
</form>
<?php
get_footer();
?>

Step 2: Implement AJAX for Form Submission

2.1 Enqueue jQuery (if not already loaded)
In your theme’s functions.php file, enqueue jQuery if it’s not already loaded:

add_action('wp_enqueue_scripts', 'enqueue_custom_scripts');
function enqueue_custom_scripts() {
    wp_enqueue_script('jquery');
}

2.2 AJAX for Login Form
In your custom-login.php file, add the following JavaScript code to handle the login form submission:

jQuery(document).ready(function($) {
    jQuery("#login-form").on("submit", function (e) {
        e.preventDefault();
        e.isDefaultPrevented();

        var form = jQuery(this);
        var error;
        var user_email = form.find("#user_email");
        var user_password = form.find("#user_password");
        var security = form.find("#login_user_nonce");

        jQuery.ajax({
            type: "POST",
            dataType: "json",
            url: '<?= esc_url(admin_url('admin-ajax.php')); ?>',
            data: {
                action: "ajax_login_user",
                user_email: user_email.val(),
                user_password: user_password.val(),
                security: security.val(),
            },
            success: function (response) {
            	if (response.success) {
            	    $('.alert').text(response.msg).show();
                    window.setTimeout(function () {
                        window.location = response.redirect;
            	    }, 500);
            	} else {
            	    $('.alert').text(response.msg).show();
            	    $("html, body").animate({ scrollTop: 0 }, "slow");
            	}
            },
            error: function (jqXHR, exception) {
                var msg = "";
                if (jqXHR.status === 0) {
                    msg = "Not connect.\n Verify Network.";
                } else if (jqXHR.status == 404) {
                    msg = "Requested page not found. [404]";
                } else if (jqXHR.status == 500) {
                    msg = "Internal Server Error [500].";
                } else if (exception === "parsererror") {
                    msg = "Requested JSON parse failed.";
                } else if (exception === "timeout") {
                    msg = "Time out error.";
                } else if (exception === "abort") {
                    msg = "Ajax request aborted.";
                } else if (jqXHR.responseText === "-1") {
                    msg = "Please refresh page and try again.";
                } else {
                    msg = "Uncaught Error.\n" + jqXHR.responseText;
                }
                $('.alert').text(msg).show();
            },
        });
    });
});

2.3 AJAX for Register Form
Similarly, in your custom-register.php file, add the following JavaScript code for the registration form:

jQuery(document).ready(function($) {
    $('#register-form').on('submit', function (e) {
        e.preventDefault();
        e.isDefaultPrevented();

        var form = jQuery(this);
        var user_first_name = form.find("#user_first_name");
        var user_last_name = form.find("#user_last_name");
        var user_email = form.find("#user_email");
        var user_password = form.find("#user_password");
        var user_cpassword = form.find("#user_cpassword");
        var security = form.find("#register_user_nonce");

        jQuery.ajax({
            type: "POST",
            dataType: "json",
            url: '<?= esc_url(admin_url('admin-ajax.php')); ?>',
            data: {
                action: "ajax_register_user",
                user_first_name: user_first_name.val(),
                user_last_name: user_last_name.val(),
                user_email: user_email.val(),
                user_password: user_password.val(),
                user_cpassword: user_cpassword.val(),
                security: security.val(),
            },
            success: function (response) {
                if (response.success) {
		    $('.alert').text(response.msg).show();

                    window.setTimeout(function () {
                        window.location = response.redirect;
                    }, 500);
                } else {
		    $('.alert').text(response.msg).show();
		    $("html, body").animate({ scrollTop: 0 }, "slow");
            	}
            },
            error: function (jqXHR, exception) {
                var msg = "";
                if (jqXHR.status === 0) {
                    msg = "Not connect.\n Verify Network.";
                } else if (jqXHR.status == 404) {
                    msg = "Requested page not found. [404]";
                } else if (jqXHR.status == 500) {
                    msg = "Internal Server Error [500].";
                } else if (exception === "parsererror") {
                    msg = "Requested JSON parse failed.";
                } else if (exception === "timeout") {
                    msg = "Time out error.";
                } else if (exception === "abort") {
                    msg = "Ajax request aborted.";
                } else if (jqXHR.responseText === "-1") {
                    msg = "Please refresh page and try again.";
                } else {
                    msg = "Uncaught Error.\n" + jqXHR.responseText;
                }
                $('.alert').text(msg).show();
            },
        });
    });
});

Step 3: Handle AJAX Requests in WordPress

3.1 Process AJAX Login Request
In your theme’s functions.php file, handle the AJAX login request:

/**
 * Ajax login
 *
 * @return json
 */
add_action('wp_ajax_nopriv_ajax_login_user',  'ajax_login_user');
function ajax_login_user() {
    $user_email = sanitize_email( $_POST['user_email'] );
    $user_password = sanitize_text_field( $_POST['user_password'] );

    // First check the nonce, if it fails the function will break
    if( !check_ajax_referer( 'login_user_nonce', 'security', false) ) :
        echo json_encode(
            array(
                'success' => false, 
                'msg' => 'Session token has expired, please reload the page and try again',
            )
        );
        die();
    endif;

    // if user_email is empty then return
    if ( !$user_email ) {
        echo json_encode(
            array(
                'registered' => false, 
                'msg' => 'Please fill email address',
            )
        );
        die();
    }

    // if user_email is not valid then return
    if ( !is_email($user_email)  ) {
        echo json_encode(
            array(
                'registered' => false, 
                'msg' => 'This is not valid email address',
            )
        );
        die();
    }

    // if user_password is empty then return
    if(empty($user_password)) {
        echo json_encode(
            array(
                'registered' => false, 
                'msg' => 'Please provide password',
            )
        );
        die();
    }

    $info = [
        'user_login' => $user_email,
        'user_password' => $user_password,
        'remember' => true,
    ];

    // now sign on user
    $user_signon = wp_signon( $info, '' );

    // if login details is wrong then give a alert else login user
    if ( is_wp_error($user_signon) ) {
        echo json_encode(
            array(
                'success' => false, 
                'msg' => 'Wrong username or password.',
            )
        );
    } else {
        wp_clear_auth_cookie();
        wp_set_current_user($user_signon->ID);
        wp_set_auth_cookie($user_signon->ID, true);
        echo json_encode(
            array(
                'success' => true, 
                'msg' => 'Login successful, redirecting...',
                'redirect' => site_url('my-account'),
            
            )
        );
    }
    die();
}

3.2 Process AJAX Register Request
Similarly, handle the AJAX register request:

/**
 * Ajax register
 *
 * @return json
 */
add_action( 'wp_ajax_nopriv_ajax_register_user', 'ajax_register_user' );
public function ajax_register_user() {
    $user_first_name = sanitize_text_field( $_POST['user_first_name'] );
    $user_last_name = sanitize_text_field( $_POST['user_last_name'] );
    $user_email = sanitize_email( $_POST['user_email'] );
    $user_password = sanitize_text_field( $_POST['user_password'] );
    $user_cpassword = sanitize_text_field( $_POST['user_cpassword'] );

    // First check the nonce, if it fails the function will break
    if( !check_ajax_referer( 'register_user_nonce', 'security', false) ) :
        echo json_encode(
            array(
                'registered' => false, 
                'msg' => 'Session token has expired, please reload the page and try again'
            )
        );
        die();
    endif;

    // if user_first_name is empty then return
    if(empty($user_first_name)) {
        echo json_encode(
            array(
                'registered' => false, 
                'msg' => 'Please provide your first name'
            )
        );
        die();
    }  

    // if user_last_name is empty then return
    if(empty($user_last_name)) {
        echo json_encode(
            array(
                'registered' => false, 
                'msg' => 'Please provide your last name',
            )
        );
        die();
    }

    // if user_email is empty then return
    if ( !$user_email ) {
        echo json_encode(
            array(
                'registered' => false, 
                'msg' => 'Please fill email address',
            )
        );
        die();
    }

    // if user_email is not valid then return
    if ( !is_email($user_email)  ) {
        echo json_encode(
            array(
                'registered' => false, 
                'msg' => 'This is not valid email address',
            )
        );
        die();
    }

    // if user_password is empty then return
    if(empty($user_password)) {
        echo json_encode(
            array(
                'registered' => false, 
                'msg' => 'Please provide password',
            )
        );
        die();
    }
    
    // if user confirm password is empty then return
    if(empty($user_cpassword)) {
        echo json_encode(
            array(
                'registered' => false, 
                'msg' => 'Please confirm password',
            )
        );
        die();
    }

    // if password is not strong then return
    $uppercase = preg_match('@[A-Z]@', $user_password);
    $lowercase = preg_match('@[a-z]@', $user_password);
    $number    = preg_match('@[0-9]@', $user_password);
    $specialChars = preg_match('@[^\w]@', $user_password);

    if(!$uppercase || !$lowercase || !$number || !$specialChars || strlen($user_password) < 8) {
        echo json_encode(
            array(
                'registered'=>false, 
                'msg'=> 'Password should be at least 8 characters in length and should include at least one upper case letter, one number, and one special character.',
            )
        );
        die();
    }

    // if email not exist then register user and login
    if( email_exists($user_email) == false ) {
	$user_name = explode( '@', $user_email);
        $username = $user_name[0];

        // check if username is exist else generate new
        if (username_exists($username)) {
            $random = rand(10,100);
            $username = $username . '-' . $random;
        }

	$user_data = array(
            'first_name'    => $user_first_name,
            'last_name'     => $user_last_name,
            'user_login'    => $username,
            'user_email'    => $user_email,
            'user_pass'     => $user_password,
        );

        // insert new user
        $user_id = wp_insert_user( $user_data );

        $info = [
            'user_login' => $user_email,
            'user_password' => $user_password;
            'remember' => true,
        ];

        $user_signon = wp_signon( $info, '' );

        // login user
        wp_clear_auth_cookie();
        wp_set_current_user($user_signon->ID);
        wp_set_auth_cookie($user_signon->ID, true);
    
        echo json_encode(
            array(
                'success' => true, 
                'redirect' => site_url('my-account'),
                'msg' => 'You have successfully logged in. Redirecting please wait....',
            )
        );
        die();
    } else {
	echo json_encode(
    	    array(
    		'success' => false, 
    		'msg' => 'Email already exist, please try other one.',
    	    )
    	);
        die();
    }
    die();
}

Conclusion

In this post we have created login and register form using custom page template. You can use a shortcode function to create a WordPress login and register form in WordPress without a plugin. I hope you can now implement one of these methods to create a custom front-end login and register form on your WordPress site.

Leave a Reply

Your email address will not be published. Required fields are marked *

The link has been Copied to clipboard!