Custom User Login/Signin Using AJAX – WordPress
Yesterday I’ve posted a fresh tutorial for Custom User Registration/Signup Using AJAX in WordPress and few years back I also posted a pure PHP Login/Signin in WordPress and today I’ve decided why not upgrade this outdated pure PHP Login/Signin script too?
We do use the same WordPress function on signing user in but only this time it’s done via WP AJAX.
Let’s get started.
HTML Code
This is just a normal HTML code and form for user to input username and password.
<div class="userLogin">
<?php
// check if the user already login
if( is_user_logged_in() ) { ?>
<p>It seems that you're already loggedin, <a href="<?php echo wp_logout_url( get_permalink() ); ?>">logout</a> to login with different account or register new account</p>
<?php } else { ?>
<!--message wrapper-->
<div id="message" class="alert-box"></div>
<h2>LOGIN</h2>
<form method="post" id="rsUserLogin">
<?php
// this prevent automated script for unwanted spam
if ( function_exists( 'wp_nonce_field' ) )
wp_nonce_field( 'rs_user_login_action', 'rs_user_login_nonce' );
?>
<p><input type="text" name="log" id="log" placeholder="Username" /></p>
<p><input type="password" name="pwd" id="pwd" placeholder="Password" /></p>
<p>
<label>
<input type="checkbox" name="remember" id="remember" value="true" /> Remember Me
</label>
</p>
<p>
<input type="submit" id="submit" class="button btn-outline" value="Login" />
<!--make sure your theme has ajax-loader.gif added under /images directory-->
<img src="<?php echo get_stylesheet_directory_uri(); ?/>/images/ajax-loader.gif" id="preloader" alt="Preloader" />
<!--where you'd like your user after logged in?, this set to current page-->
<input type="hidden" name="redirection_url" id="redirection_url" value="<?php echo get_permalink( get_the_ID() ); ?/>" />
</p>
</form>
<?php } ?>
</div>
JS Code
Location and filename: THEME_DIRECTORY/js/theme-ajax.js
This code sends and display returned data in PHP code below
jQuery(document).ready(function($) {
// for user login form
$("form#rsUserLogin").submit(function(){
var submit = $(".userLogin #submit"),
preloader = $(".userLogin #preloader"),
message = $(".userLogin #message"),
contents = {
action: 'user_login',
nonce: this.rs_user_login_nonce.value,
log: this.log.value,
pwd: this.pwd.value,
remember: this.remember.value,
redirection_url: this.redirection_url.value
};
// disable button onsubmit to avoid double submision
submit.attr("disabled", "disabled").addClass('disabled');
// Display our pre-loading
preloader.css({'visibility':'visible'});
// on my previous tutorial it just simply returned HTML but this time I decided to use JSON type so we can check for data success and redirection url.
$.post( theme_ajax.url, contents, function( data ){
submit.removeAttr("disabled").removeClass('disabled');
// hide pre-loader
preloader.css({'visibility':'hidden'});
// check response data
if( 1 == data.success ) {
// redirect to home page
window.location = data.redirection_url;
} else {
// display return data
message.html( '<p class="error">' + data + '</p>' );
}
}, 'json');
return false;
});
});
PHP Code
You can paste this code into your current theme’s functions.php
file or create another file if you prefer.
add_action( 'wp_ajax_nopriv_user_login', 'rs_user_login_callback' );
add_action( 'wp_ajax_user_login', 'rs_user_login_callback' );
/*
* @desc Process theme login
*/
function rs_user_login_callback() {
global $wpdb;
$json = array();
$error = '';
$success = '';
$nonce = $_POST['nonce'];
if ( ! wp_verify_nonce( $nonce, 'rs_user_login_action' ) )
die ( '<p class="error">Security checked!, Cheatn huh?</p>' );
//We shall SQL escape all inputs to avoid sql injection.
$username = $wpdb->escape($_POST['log']);
$password = $wpdb->escape($_POST['pwd']);
$remember = $wpdb->escape($_POST['remember']);
$redirection_url = $wpdb->escape($_POST['redirection_url']);
if( empty( $username ) ) {
$json[] = 'Username field is required.';
} else if( empty( $password ) ) {
$json[] = 'Password field is required.';
} else {
$user_data = array();
$user_data['user_login'] = $username;
$user_data['user_password'] = $password;
$user_data['remember'] = $remember;
$user = wp_signon( $user_data, false );
if ( is_wp_error($user) ) {
$json[] = $user->get_error_message();
} else {
wp_set_current_user( $user->ID, $username );
do_action('set_current_user');
$json['success'] = 1;
$json['redirection_url'] = $redirection_url;
}
}
echo json_encode( $json );
// return proper result
die();
}
Workaround
By default wp_ajax
didn’t work in front-end or submitting data to admin-ajax.php
file in front-end directly, luckily WordPress has wp_localize_script()
function we can use, this function localizes a registered script with data for a JavaScript variable.
Paste the below code into your functions.php
file, to avoid any conflict I suggest add it in init action
// localize wp-ajax, notice the path to our theme-ajax.js file
wp_enqueue_script( 'rsclean-request-script', get_stylesheet_directory_uri() . '/js/theme-ajax.js', array( 'jquery' ) );
wp_localize_script( 'rsclean-request-script', 'theme_ajax', array(
'url' => admin_url( 'admin-ajax.php' ),
'site_url' => get_bloginfo('url'),
'theme_url' => get_bloginfo('template_directory')
) );
Hope that helps, Happy coding ^_^