Warning: Undefined array key "show" in /home/shtechno/public_html/shivamkhare.in/wp-content/themes/shivam/header.php on line 13
Warning: Undefined variable $bodyClass in /home/shtechno/public_html/shivamkhare.in/wp-content/themes/shivam/header.php on line 50
class="post-template-default single single-post postid-152 single-format-standard vertical">

WordPress custom login code

In this blog, you’ll learn how to create WordPress login with custom code through AJAX with Cross-Site Request Forgery (CSRF) protection.

CSRF Description:

Cross-Site Request Forgery (CSRF) allows an attacker to execute actions on behalf of an unwitting user who is already authenticated with your web application. If successful, user data and user actions can be compromised. If the user who is attacked with CSRF happens to be an administrator, the entire web application should be considered compromised. CSRF occurs when a user submits data to a form or input he/she did not intend; usually an attacker will accomplish this by sending them a link or convincing them to input to a different form that looks similar and posts to the same place.

How to fix:

A unique token that guarantees freshness of submitted data must be added to all web application elements that can affect business logic.

WordPress Redirection

Firstly we have to create page redirection for if you are already logged in so auto redirect to dashboard page or if you not logged in user so automatic redirect to Login page.

Following code you have to paste in your function.php or paste the top of the header.php (see screenshot of header.php)

Copy the code from here:

    wp_redirect ('/login/'); 
}elseif(is_page('login') && is_user_logged_in()){
    wp_redirect ('/dashboard/'); 

Create login form

Code for login page or template-login.php.

Here the code for login form with Nonces.

<div class="login-block">
    <h1>Member Login</h1>
    <form method="post" action="/submit_login/" id="loginform" enctype="multipart/form-data" >
      <div class="field-group mb-3">
         <label for="username">Username</label>
         <input type="text" name="username" id="username" class="form-control" />
         <label id="error_usernm" class="error"></label> <!-- show error -->
      <div class="field-group mb-3">
         <label for="password">Password</label>
         <input type="password" name="password" id="password" class="form-control" autocomplete="off" />
         <label id="error_password" class="error"></label> <!--show error-->
      <div class="field-group mb-3">
         <div class="rememberme">
	   <label for="rememberme">
	      <input type="checkbox" name="rememberme" value="forever" checked="checked" id="rememberme" tabindex="13" /> Remember me
        <?php wp_nonce_field( 'submit_login' ); //"submit_login" same as action url ?>
       <input type="submit" class="loginsubmit" value="Login" />
        <div id="formerror" ></div> <!-- Display result here-->

On the front end, suppose we wanted to add a nonce to a form submission. We’ll do this with the wp_nonce_field convenience function:

Form validation and Submit

Click on the submit button firstly we have to check the input field valid or not with jQuery validation (Username or Password are protracted) then process to login check.

Copy the code for custom.js or footer.php

    var username  = $.trim($('#username').val());
    var password  = $.trim($('#password').val());
    var errCnt = 0;
    var emailRegEx=/^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;

        $('#error_usernm').html('Please enter username.').css('visibility', 'visible');
        errCnt += 1;

        $('#error_password').html('Please enter password.').css('visibility', 'visible');
        errCnt += 1;

    var formData=$('#loginform').serialize();
    var data = formData+'&action=submit_check_login';
    var ajaxurl = '/wp-admin/admin-ajax.php';
    if(errCnt == 0){
       $.post(ajaxurl, data, function(response) {
           var error = response.split('+');
           if(error[0] == 'success'){
               window.location.href = window.location.origin + '/meeting-note/';
                $('#formerror').html(error[0]).css('visibility', 'visible');
           }, 4000);

Check User or go to login

Copy the code for function.php

add_action( 'wp_ajax_submit_check_login', 'submit_check_login' );
add_action( 'wp_ajax_nopriv_submit_check_login', 'submit_check_login' );
function submit_check_login(){
    global $wpdb;
    $nonce = $_REQUEST['_wpnonce'];
    if ( ! wp_verify_nonce( $nonce, 'submit_login' ) ) {
        exit; // Get out of here, the nonce is rotten!

    // Now we can process the submission
    if (isset( $_REQUEST['username'] )  && isset( $_REQUEST['password'] )){
    //We shall SQL escape all inputs
    $username = $wpdb->escape($_POST['username']);
    $password = $wpdb->escape($_POST['password']);
    $remember = $wpdb->escape($_POST['rememberme']);
    if($remember) $remember = "true";
    else $remember = "false";
    $login_data = array();
    $login_data['user_login'] = $username;
    $login_data['user_password'] = $password;
    $login_data['remember'] = $remember;
    $user_verify = wp_signon( $login_data, false ); 
    if ( is_wp_error($user_verify) ){
        echo $error = "Invalid login details";
     } else {  
        echo $error = "success";

The nonce is unknown to the hacker, he can’t craft a fake link that will do harm. Any malicious attempts will be squashed at the wp_verify_nonce check. We’ve stopped the hacker, right?! For many cases, yes. We’ve made it much more difficult for a hacker to forge a request.

wp_signon is a wordpress function to verify user.