I’m using wp_login_form() to display login form in a jQuery dialog window.
If user enters wrong password, the user is taken to the backend. I don’t want that. Is there a way to notify user that he entered wrong password and still remain on the same page?
Before wp_login_form() came I was using a plugin. I’m kind of hoping I can avoid using a plugin for this.
My code:
wp_login_form( array( 'label_remember' => __( 'Remember me' ), 'label_log_in' => __( 'Login' ) ) );
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
wp_login_form() creates a form with an action attribute of site_url/wp-login.php, which means that when you click the submit button the form is posted to site_url/wp-login.php which ignores redirect_to on errors (like wrong password) so in your case either go back to using a plugin or recreate the whole login process and that way you will have control on errors, take a look at Check for correct username on custom login form which is very similar question.
Method 2
I came here from google. But the answer didn’t satisfy me. I was looking for a while and found a better solution.
Add this to your functions.php:
add_action( 'wp_login_failed', 'my_front_end_login_fail' ); // hook failed login
function my_front_end_login_fail( $username ) {
$referrer = $_SERVER['HTTP_REFERER']; // where did the post submission come from?
// if there's a valid referrer, and it's not the default log-in screen
if ( !empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin') ) {
wp_redirect( $referrer . '?login=failed' ); // let's append some information (login=failed) to the URL for the theme to use
exit;
}
}
Method 3
The current method I am using to deal with all of the issues outlined here works great even with blank username/password and doesn’t rely on javascript (though the js could be good along with this).
add_action( 'wp_login_failed', 'custom_login_failed' );
function custom_login_failed( $username )
{
$referrer = wp_get_referer();
if ( $referrer && ! strstr($referrer, 'wp-login') && ! strstr($referrer,'wp-admin') )
{
wp_redirect( add_query_arg('login', 'failed', $referrer) );
exit;
}
}
The key is this filter to change how a blank username/password is treated:
add_filter( 'authenticate', 'custom_authenticate_username_password', 30, 3);
function custom_authenticate_username_password( $user, $username, $password )
{
if ( is_a($user, 'WP_User') ) { return $user; }
if ( empty($username) || empty($password) )
{
$error = new WP_Error();
$user = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.'));
return $error;
}
}
You can take this a step further and completely replace wp-login.php by redirecting users to your custom login page and use that page for the login_failed redirect also. Full code:
/**
* Custom Login Page Actions
*/
// Change the login url sitewide to the custom login page
add_filter( 'login_url', 'custom_login_url', 10, 2 );
// Redirects wp-login to custom login with some custom error query vars when needed
add_action( 'login_head', 'custom_redirect_login', 10, 2 );
// Updates login failed to send user back to the custom form with a query var
add_action( 'wp_login_failed', 'custom_login_failed', 10, 2 );
// Updates authentication to return an error when one field or both are blank
add_filter( 'authenticate', 'custom_authenticate_username_password', 30, 3);
// Automatically adds the login form to "login" page
add_filter( 'the_content', 'custom_login_form_to_login_page' );
/**
* Custom Login Page Functions
*/
function custom_login_url( $login_url='', $redirect='' )
{
$page = get_page_by_path('login');
if ( $page )
{
$login_url = get_permalink($page->ID);
if (! empty($redirect) )
$login_url = add_query_arg('redirect_to', urlencode($redirect), $login_url);
}
return $login_url;
}
function custom_redirect_login( $redirect_to='', $request='' )
{
if ( 'wp-login.php' == $GLOBALS['pagenow'] )
{
$redirect_url = custom_login_url();
if (! empty($_GET['action']) )
{
if ( 'lostpassword' == $_GET['action'] )
{
return;
}
elseif ( 'register' == $_GET['action'] )
{
$register_page = get_page_by_path('register');
$redirect_url = get_permalink($register_page->ID);
}
}
elseif (! empty($_GET['loggedout']) )
{
$redirect_url = add_query_arg('action', 'loggedout', custom_login_url());
}
wp_redirect( $redirect_url );
exit;
}
}
function custom_login_failed( $username )
{
$referrer = wp_get_referer();
if ( $referrer && ! strstr($referrer, 'wp-login') && ! strstr($referrer, 'wp-admin') )
{
if ( empty($_GET['loggedout']) )
wp_redirect( add_query_arg('action', 'failed', custom_login_url()) );
else
wp_redirect( add_query_arg('action', 'loggedout', custom_login_url()) );
exit;
}
}
function custom_authenticate_username_password( $user, $username, $password )
{
if ( is_a($user, 'WP_User') ) { return $user; }
if ( empty($username) || empty($password) )
{
$error = new WP_Error();
$user = new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Invalid username or incorrect password.'));
return $error;
}
}
function custom_login_form_to_login_page( $content )
{
if ( is_page('login') && in_the_loop() )
{
$output = $message = "";
if (! empty($_GET['action']) )
{
if ( 'failed' == $_GET['action'] )
$message = "There was a problem with your username or password.";
elseif ( 'loggedout' == $_GET['action'] )
$message = "You are now logged out.";
elseif ( 'recovered' == $_GET['action'] )
$message = "Check your e-mail for the confirmation link.";
}
if ( $message ) $output .= '<div class="message"><p>'. $message .'</p></div>';
$output .= wp_login_form('echo=0&redirect='. site_url());
$output .= '<a href="'. wp_lostpassword_url( add_query_arg('action', 'recovered', get_permalink()) ) .'" rel="nofollow noreferrer noopener" title="Recover Lost Password">Lost Password?</a>';
$content .= $output;
}
return $content;
}
Customize and add these to add your logo to the wp-login page for password recovery:
// calling it only on the login page
add_action( 'login_enqueue_scripts', 'custom_login_css', 10 );
function custom_login_css() { wp_enqueue_style( 'custom_login_css', get_template_directory_uri() .'/library/css/login.css', false ); }
// changing the logo link from wordpress.org to your site
add_filter( 'login_headerurl', 'custom_login_logo_url' );
function custom_login_logo_url() { return home_url(); }
// changing the alt text on the logo to show your site name
add_filter( 'login_headertitle', 'custom_login_title' );
function custom_login_title() { return get_option('blogname'); }
Login logo css:
.login h1 a {
background: url(../images/login-logo.png) no-repeat top center;
width: 274px;
height: 63px;
text-indent: -9999px;
overflow: hidden;
padding-bottom: 15px;
display: block;
}
EDIT: I just implemented this on another site form scratch, and found the above “step further” to be more complete, and fixed small syntax errors in the “add_actions”. Added some comments and a method to automatically add the login form to login page without a separate template file. The login form method should work in most instances, since it is attached to “the_content”, it could cause and issue if you have more than one loop on the login page, just use a page-login.php template in that case.
Method 4
A solution for Szczepan Hołyszewski’s point about empty fields in the accepted solution, the following jQuery will prevent going to the standard wp-login page: (add to login page template or footer.php)
jQuery("#loginform-custom").submit(function(){
var isFormValid = true;
jQuery("input").each(function()
{
if (jQuery.trim($(this).val()).length == 0){
jQuery(this).addClass("submit_error");
isFormValid = false;
}
else {
jQuery(this).removeClass("submit_error");
}
});
return isFormValid;
});
Method 5
The following worked for me. Both of these hooks can be found within the function wp_authenticate within wp-includes/puggabel.php.
- Check via the
authenticatefilter if the login form is missing the username or password.
function wpse_15633_redirectMissingDataLoginForm($user, $username, $password)
{
$errors = [];
empty(trim($password)) && $errors[] = 'password_empty';
empty(trim($username)) && $errors[] = 'username_empty';
if (! empty($errors)) {
$redirect_url = add_query_arg([
'errors' => join(',', $errors),
], site_url('login', 'login_post'));
if (wp_safe_redirect($redirect_url)) {
exit;
}
}
return $user;
}
add_filter('authenticate', 'wpse_15633_redirectMissingDataLoginForm', 10, 3);
- Check via the
wp_login_failedaction if the authentication of the supplied username and password has failed.
function wpse_15633_redirectFailedLoginForm($username, $error)
{
$redirect_url = add_query_arg([
'errors' => $error->get_error_code(),
], site_url('login', 'login_post'));
if (wp_safe_redirect($redirect_url)) {
exit;
}
}
add_action('wp_login_failed', 'wpse_15633_redirectFailedLoginForm', 10, 2);
Method 6
One addition to Alexey’s answer. You can add a jquery function to check that one of the fields is not blank. That way the form will not submit unless there is something to check, preventing WordPress from redirecting to /wp-login.php.
<script>
$("#wp-submit").click(function() {
var user = $("input#user_login").val();
if (user == "") {
$("input#user_login").focus();
return false;
}
});
</script>
Still not sure how to fix the forgot password aspect
Method 7
jQuery("#loginform-custom").submit(function(){
var isFormValid = true;
jQuery("input").each(function()
{
if (jQuery.trim($(this).val()).length == 0){
jQuery(this).addClass("submit_error");
isFormValid = false;
}
else {
jQuery(this).removeClass("submit_error");
}
});
return isFormValid;
});
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0