wordpress authentication - redirect after incorrect login

 

[caption id="" align="alignright" width="300" caption="Image via Wikipedia"]The logo of the blogging software WordPress.[/caption]

Few days ago I had to deploy a simple wordpress installation for a project at @therumpusroom_ with my buddy @twentyrogersc. Super simple, yet it presented a little issue: having a personalized authentication form, displayed on a wordpress page, it was re-directing to the default login screen after specifying incorrect credentials. It came out that we needed to implement the whole authentication mechanism on a page, hence tweaking the simple post form to send data to itself instead of submitting to wp-login.php (which, btw is working fine if users provide the correct credentials, and also accept a redirect parameter to make users land on a pre-determined page).

Just for my records, I leave the code here, and I hope I could save some time to people who incur in the same problem. Here's my solution:

  1. from the dashboard create a page and give it a meaningful permalink, such as log-in
  2. create a php file and give it a name according to the wordpress convention: page-<permalink>.php (in my case: page-log-in.php)
  3. write the php code to perform the whole authentication (hence including password check and signon), this is my code:
    <?php
        // if user is logged in, redirect whereever you want
        if (is_user_logged_in()) {
            header('Location: '.get_option('siteurl').'/how-to');
            exit;
        }
    
        // if this page is receiving post data
        // means that someone has submitted the login form
        if( isset( $_POST['log'] ) ) {
            $incorrect_login = TRUE;
            $log = trim( $_POST['log'] );
            $pwd = trim( $_POST['pwd'] );
    
            // check if username exists
            if ( username_exists( $log ) ) {
                // read user data
                $user_data = get_userdatabylogin( $log );
    
                // create the wp hasher to add some salt to the md5 hash
                require_once( ABSPATH.'/wp-includes/class-phpass.php');
                $wp_hasher = new PasswordHash( 8, TRUE );
                // check that provided password is correct
                $check_pwd = $wp_hasher->CheckPassword($pwd, $user_data->user_pass);
    
                // if password is username + password are correct
                // signon with wordpress function and redirect wherever you want
                if( $check_pwd ) {
                    $credentials = array();
                    $credentials['user_login'] = $log;
                    $credentials['user_password'] = $pwd;
                    $credentials['remember'] = isset($_POST['rememberme']) ? TRUE : FALSE;
    
                    $user_data = wp_signon( $credentials, false );
                    header('Location: '.site_url('how-to'));
                }
                else {
                    // don't need to do anything here, just print some error message
                    // in the form below after checking the variable $incorrect_login
                }
            }
        }
    
        // and finally print the form, just be aware the action needs to go to "self",
        // hence we're using echo site_url('log-in'); for it
    ?>
    <?php get_header(); ?>
    
        <h2>log in</h2>
        <form action="<?php echo site_url('log-in'); ?>" method="post" id="login-form">
            <label for="log">User</label>
            <input type="text" name="log" id="log" class="text" value="<?php echo wp_specialchars(stripslashes($user_login), 1) ?>" size="20" />
    
            <label for="pwd">Password</label>
            <input type="password" name="pwd" id="pwd" class="text" size="20" />
    
            <label for="rememberme"><input name="rememberme" id="rememberme" type="checkbox" checked="checked" value="forever" /> Remember me</label>
    
            <input type="hidden" name="redirect_to" value="<?php echo get_option('siteurl'); ?>/how-to" />
            <input type="submit" name="submit" value="log in" class="button" />
        </form>
    <?php
        // incorrect credentials, print an error message
        if( TRUE == $incorrect_login ) {
    ?>
            <div class="incorrect_login">Incorrect login details. Please confirm the fields and submit it again,
            or <a href="<?php echo site_url('contact-us'); ?>">contact us</a> to obtain a set of credentials.</div>
    <?php
        }
    ?>   
    
    <?php get_footer(); ?>
  4. and finally load this php file where your wordpress theme lives, it's done!