WordPress Login Security Custom Login Page

label_outlinechat_bubble_outline Comment

WordPress login security is an important part of protecting your WordPress site against brute force login attempts. This is part 2 of 3 on how to protect your WordPress login. In part 2 we are going to show you how to create a custom login page. This page will be used in lieu of the default wp-login.php.

Hey now, isn’t there a plugin for this?

There are quite a few plugins out there that allow you to create custom login pages. In reality they just make it easy to edit the default wp-login.php page. The purpose of changing the login page is to help prevent WordPress based brute force attacks. Every hacker, script kiddy, etc in the world knows that domain.tld/wp-login.php is the WP default login page. They also know that WP is the most commonly used CMS. The combination of the 2 = HUGE TARGET.

Lets get started:

First you need to access your themes funtions.php file. Edit this file and at the top, but within the php tags place the following:

function redirect_login_page(){
$page_accessed = basename($_SERVER['REQUEST_URI']);
$newLogin_page  = 'https://domain.tld/userlogin/'; 
if( $page_accessed == "wp-login.php" && $_SERVER['REQUEST_METHOD'] == 'GET') {
	wp_redirect($newLogin_page);
  exit();
	}
}

What we are doing here initially is checking the page request from the browser. We then give the instructions on where the redirect is supposed to go. This is where you will edit the code and replace domain.tld with your domain name. You can also change the page slug if you wish as well. On the next line we make sure that the wp-login.php was the page requested via the information gathered on line number 1. We them make sure that the request isn’t coming from the form that we will be creating.

Be sure not to save this unless you have FTP access to the site or you are already logged in. We still haven’t created the form to login. If the page and form that we are re-directing to doesn’t exist then ask yourself … how you plan on logging in?

As an additional security measure you can block/forbid around 98% of automated Brute Force Login hacking attempts (since typically Server Protocol HTTP/1.0 is used in these automated Brute Force Login Attacks) by putting the following piece of code in your .htaccess file. We recommend doing this as these attacks will be blocked before they hit the script which reduces server load.

# Protect wp-login.php from Brute Force Login Attacks based on Server Protocol
# All legitimate humans and bots should be using Server Protocol HTTP/1.1
RewriteCond %{REQUEST_URI} ^/wp-login\.php$
RewriteCond %{THE_REQUEST} HTTP/1\.0
RewriteRule ^(.*)$ - [F,L]

Thanks to the AIT Pro Admin, BulletProof Security Pro, for the above piece of information via this link.

For the next step we have a couple of options. You can do things the proper way and create a new template for the login script or you can use one of those plugins that will allow you to use php in your pages. If you decide to create a custom page template you can pay yourself on the back. If you decide that you want to use a plugin I would recommend using Shortcode Exec PHP. It’s a neat little plugin that allows you to make custom shortcodes using PHP. Those shortcodes can then be used in the page.

Can you explain how to make a custom page template?

Well… I would hope that if you’ve gotten to step 2 of this guide that you know how to make one already. If you don’t, there’s a wealth of information out there on how to do so.

Can you explain how to use Shortcode Exec PHP?

The plugin is well documented and there’s plenty of “how-to” information on the WP Plugin site.

The code that we’ll want to place in the custom page template, or in most cases, the custom content template will be:

<?php if ( is_user_logged_in() ) { ?>
<div class="template-notice info">
	<p>
		<?php $current_user = wp_get_current_user();
		_e( 'Hey ' . $current_user->display_name . '! Welcome back!' ); ?>
	</p>
</div>
<?php } else { ?>
	<form method="post" action="<?php echo site_url( '/wp-login.php' ); ?>
		 " class="user-login-form">
		<fieldset class="login-form">
			<legend>Log In</legend>
			<div class="login-username">
				<label for="user_login">Username: </label>
				<input type="text" name="log" value="" size="20" id="user_login" tabindex="101"/>
			</div>
			<div class="login-password">
				<label for="user_pass">Password: </label>
				<input type="password" name="pwd" value="" size="20" id="user_pass" tabindex="102"/>
			</div>
			<div class="login-remember-me">
				<input type="checkbox" name="rememberme" value="forever" id="rememberme" tabindex="103"/>
				<label for="rememberme">Keep me signed in</label>
			</div>
			<div class="login-submit-wrapper">
				<button type="submit" tabindex="104" name="user-submit" class="button submit user-submit">Log In</button>
				<input type="hidden" name="user-cookie" value="1"/>
				<input type="hidden" name="_wp_http_referer" value="/userlogin/"/>
			</div>
		</fieldset>
	</form>
	<br/>
	Don't have an account yet? <a href="/user-register">Get started!</a>
<?php } ?>

It would be pretty mean not to include some basic css here right?

fieldset {border: 1px solid #C0C0C0;margin: 0 2px;padding: 0.35em 0.625em 0.75em}
.user-login-form fieldset legend {display: none}
legend {border: 0 none;padding: 0}
.user-login-form .login-username, .user-login-form .login-email, .user-login-form .login-password, .user-login-form .login-remember-me, .user-login-form .login-submit-wrapper {margin-top: 10px}
.user-login-form label {font-size: 16px;padding-bottom: 10px;display: inline-block;width: 140px}
.user-login-form .login-username input, .user-login-form .login-email input, .user-login-form .login-password input {padding: 5px}
.user-login-form .login-submit-wrapper {text-align: right;clear: both;float: right}

The button you’ll have to figure out on your own and it may automatically use the one for your theme as we classed it “button”.

We need to create a page using the template in WP. Throughout this guide we’ve used the “userlogin” slug. You can change this if you’d like, but be sure to change it throughout if you do so.

You should be able to access the page now and see the login box.

But wait, what about the registration form and password reset?

We created links to these in the form but we never created them. For the registration form I would HIGHLY recommend using Gravity Forms. If you get Gravity Forms you can create a custom registration page that’s very configurable with a ton of options including spam-protection and variable options. I can’t speak highly enough of Gravity forms and would recommend it to any developer or WP user.

For those that choose not to use Gravity Forms (sigh) here’s some code for another custom template:

<form method="post" action="https://domain.tld/wp-login.php" class="user-login-form">
	<fieldset class="login-form">
		<legend>Create an Account</legend>
		<div class="login-template-notice">
			<p>Your username must be unique, and cannot be changed later.</p>
			<p>We use your email address to email you a secure password and verify your account.</p>
		</div>
		<div class="login-username">
			<label for="user_login">Username: </label>
			<input type="text" name="user_login" value="" size="20" id="user_login" tabindex="101" />
		</div>
		<div class="login-email">
			<label for="user_email">Email: </label>
			<input type="text" name="user_email" value="" size="20" id="user_email" tabindex="102" />
		</div>
		<div class="login-submit-wrapper">
			<button type="submit" tabindex="103" name="user-submit" class="button submit user-submit">Register</button>
		<input type="hidden" name="action" value="register" />
		<input type="hidden" name="user-cookie" value="1" />
		<input type="hidden" name="redirect_to" value="?checkemail=registered" />
                <input type="hidden" name="_wp_http_referer" value="/user-register/" />
		</div>
	</fieldset>
</form>

This page needs to have a slug of “user-register” otherwise you can change it throughout.

And lastly we need to create the password recovery page. We can do that with the below:

<form method="post" action="https://domain.tld/wp-login.php?action=lostpassword" class="user-login-form">
	<fieldset class="login-form">
		<legend>Lost Password</legend>
		<div class="login-username">
			<p>
				<label for="user_login" class="hide">Username or Email: </label>
				<input type="text" name="user_login" value="" size="20" id="user_login" tabindex="101" />
			</p>
		</div>
		<div class="login-submit-wrapper">
			<button type="submit" tabindex="102" name="user-submit" class="button submit user-submit">Reset My Password</button>
		<input type="hidden" name="user-cookie" value="1" />
		<input type="hidden" name="redirect_to" value="http://domain.tld/password-recover/?checkemail=confirm" />
                <input type="hidden" name="_wp_http_referer" value="/password-recover/" />
		</div>
	</fieldset>
</form>

This page needs to have a slug of “password-recover” otherwise you can change it throughout.

One last thing that we’ll want to do is prevent spam registration from bots. If you are using Gravity Forms this shouldn’t be an issue because there’s a couple of anti-spam measures that you can implement directly in the form. You can also add to the registration form code above something such as reCaptcha. Again however, we would rather block the attack at the entry point rather than having a form process the failure. Because the majority of bad bots use the http 1.0 protocol we’ll do that using htacess. We’ll be using a modified version of the code we used earlier. Thanks again to the AIT Pro Admin, BulletProof Security Pro, for the above piece of information via this link. Add the following to the bottom of your .htaccess file:

# Custom Anti-Spam Registration
RewriteCond %{REQUEST_URI} ^/user-register/$
RewriteCond %{HTTP_REFERER} !^.*domain.tld.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^(|-?)$ [NC,OR]
RewriteCond %{THE_REQUEST} HTTP/1\.0$
RewriteRule ^(.*)$ /spam-prevention [R=301,L]

Be aware that this will cause a re-direct to a custom page called spam-prevention. You should create this page within WordPress. Put some sort of message in there for the user to contact you if they cannot register because they have been determined to be a spam bot. In the extremely rare case that someone is using a very outdated browser (pre 1996), an outdated phone (i.e. Nokia 6310) or possibly a blind-support browser they will be redirected nicely to this page.

Check out Part 1 of WordPress Login Security here.
Check out Part 3 of WordPress Login Security here.

Get Gravity Forms here (aff link).

If you’ve found this article helpful consider leaving a comment below!

From all of us at WireFlare we ask that you help others find the answers they are looking for. Please leave a comment or share this post!

About

Blog Bio Picture For Todd

I'm the President of WireFlare. I have a passion for creativity, online business and internet security. I strive to create a community that empowers people to be themselves. I'm an adventurist, fun loving and caring. Find me hiking in places most people don't dare to go!

Get a free consultation today!