Changing the default WordPress login URL (wp-login.php) to a custom URL, such as my-custom-login, is a powerful way to enhance your site’s security. By hiding the standard login and admin URLs (wp-login.php and wp-admin), you can protect your WordPress site from brute-force attacks and automated bots. In this guide, we’ll show you how to implement a custom login URL without plugins, using custom code to return 404 errors for unauthorized access and ensure logout functionality works seamlessly.
Why Change the WordPress Login URL?
The default WordPress login URL (your-site.com/wp-login.php) is a common target for hackers. By changing it to a unique slug like my-custom-login, you add a layer of security by obscurity. Here’s why it matters:
- Prevent Brute-Force Attacks: Bots target
wp-login.phpfor login attempts. A custom URL makes it harder for them to find your login page. - Hide Admin Access: Blocking
wp-adminwith 404 errors for non-logged-in users protects your dashboard. - Improve SEO and Security: A secure site ranks better and provides a safer user experience.
Step-by-Step Guide to Change WordPress Login URL
This method uses custom PHP code added to your theme’s functions.php file (preferably in a child theme) or a custom plugin. It changes the login URL to my-custom-login, blocks wp-login.php and wp-admin with 404 errors, and ensures logout and other actions work correctly.
Step 1: Backup Your Site
Before making changes, back up your WordPress site (database and files) using a plugin like UpdraftPlus or your hosting provider’s backup tool. This ensures you can recover if anything goes wrong.
Step 2: Add the Custom Code
Copy the following code and paste it into your child theme’s functions.php file (e.g., /wp-content/themes/your-child-theme/functions.php) or a custom plugin. This code sets the login URL to my-custom-login, (Replace ‘my-custom-login’ with a unique, hard-to-guess) slug secures wp-login.php and wp-admin, and handles logout properly.
<?php
/**
* Custom code to change WordPress login URL and hide it from unauthorized access, secure wp-login.php and wp-admin, and handle logout
* Add this to your theme's functions.php or a custom plugin
*/
/**
* Define the new login URL slug
* Replace 'my-custom-login' with a unique, hard-to-guess slug
*/
define('CUSTOM_LOGIN_SLUG', 'my-custom-login');
/**
* Block direct access to wp-login.php with a 404
*/
add_action('init', function () {
global $pagenow;
if ($pagenow === 'wp-login.php') {
// Allow specific actions (logout, postpass, etc.)
$allowed_actions = ['logout', 'postpass', 'lostpassword', 'retrievepassword', 'resetpass', 'rp'];
if (isset($_GET['action']) && in_array($_GET['action'], $allowed_actions)) {
// Redirect allowed actions to custom login URL
$query_args = $_GET;
$redirect_url = home_url(CUSTOM_LOGIN_SLUG);
$redirect_url = add_query_arg($query_args, $redirect_url);
wp_safe_redirect($redirect_url);
exit;
}
// Return 404 for all other wp-login.php requests
global $wp_query;
$wp_query->set_404();
status_header(404);
nocache_headers();
get_template_part('404');
exit;
}
});
/**
* Block wp-admin for non-logged-in users with a 404
*/
add_action('admin_init', function () {
if (!is_user_logged_in() && !defined('DOING_AJAX')) {
global $wp_query;
$wp_query->set_404();
status_header(404);
nocache_headers();
wp_die('404 Not Found', '404', ['response' => 404]);
exit;
}
});
/**
* Suppress default login redirect for admin access
*/
add_filter('auth_redirect_scheme', function ($scheme) {
if (!is_user_logged_in()) {
global $wp_query;
$wp_query->set_404();
status_header(404);
nocache_headers();
get_template_part('404');
exit;
}
return $scheme;
});
/**
* Filter login URL to use custom slug
*/
add_filter('login_url', function ($login_url, $redirect, $force_reauth) {
$login_url = home_url(CUSTOM_LOGIN_SLUG);
if (!empty($redirect)) {
$login_url = add_query_arg('redirect_to', urlencode($redirect), $login_url);
}
if ($force_reauth) {
$login_url = add_query_arg('reauth', '1', $login_url);
}
return $login_url;
}, 10, 3);
/**
* Serve login pageperator; custom URL, including logout and other actions
*/
add_action('template_redirect', function () {
$request_uri = trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
if ($request_uri === CUSTOM_LOGIN_SLUG) {
global $pagenow;
$pagenow = 'wp-login.php';
nocache_headers();
// Ensure logout nonce is verified
if (isset($_GET['action']) && $_GET['action'] === 'logout' && is_user_logged_in()) {
$nonce = isset($_GET['_wpnonce']) ? $_GET['_wpnonce'] : '';
if (wp_verify_nonce($nonce, 'log-out')) {
wp_logout();
$redirect_to = !empty($_GET['redirect_to']) ? $_GET['redirect_to'] : home_url();
wp_safe_redirect($redirect_to);
exit;
}
}
require_once ABSPATH . 'wp-login.php';
exit;
}
});
/**
* Update site URL to handle custom login slug
*/
add_filter('site_url', function ($url, $path, $scheme, $blog_id) {
if (strpos($url, 'wp-login.php') !== false) {
$url = str_replace('wp-login.php', CUSTOM_LOGIN_SLUG, $url);
}
return $url;
}, 10, 4);
/**
* Handle logout URL with proper nonce
*/
add_filter('logout_url', function ($logout_url, $redirect) {
$logout_url = home_url(CUSTOM_LOGIN_SLUG . '?action=logout&_wpnonce=' . wp_create_nonce('log-out'));
if (!empty($redirect)) {
$logout_url = add_query_arg('redirect_to', urlencode($redirect), $logout_url);
}
return $logout_url;
}, 10, 2);
/**
* Update network admin URL
*/
add_filter('network_admin_url', function ($url, $path, $scheme) {
if (strpos($url, 'wp-login.php') !== false) {
$url = str_replace('wp-login.php', CUSTOM_LOGIN_SLUG, $url);
}
return $url;
}, 10, 3);
/**
* Prevent login page from being cached
*/
add_action('login_init', function () {
nocache_headers();
});
?>
Note: Use a child theme to avoid losing changes during theme updates. Alternatively, create a custom plugin by saving the code in a file like custom-login-url.php in /wp-content/plugins/.
Step 3: Test the Custom Login URL
After adding the code, test the following:
- Login: Visit
your-site.com/my-custom-login. The login page should load. - Logout: Log in, then click the logout link (e.g., in the admin menu). It should log you out and redirect to the homepage.
- Blocked URLs: Try accessing
your-site.com/wp-login.phpandyour-site.com/wp-adminwhile logged out. Both should return a 404 error. - Password Reset: Test
your-site.com/my-custom-login?action=lostpasswordto ensure it works.
Step 4: Clear Caches
If your site uses caching (e.g., WP Rocket, Cloudflare), clear all caches after adding the code. Test in an incognito browser window to avoid cached redirects.
Security Benefits
This solution enhances your WordPress site’s security by:
- Hiding the Login URL:
wp-login.phpandwp-adminare inaccessible to unauthorized users, returning 404 errors. - Preventing Redirect Exposure: No redirects reveal the
my-custom-loginURL. - Supporting All Actions: Login, logout, and password reset work seamlessly.
Additional Security Tips
To further secure your WordPress site:
- Use a Random Slug: Change my-custom-login to a unique string (e.g.,
x9k7p3m2) for better obscurity. - Enable Two-Factor Authentication: Use a plugin like Two-Factor.
- Restrict by IP: Add IP-based restrictions in
.htaccess:<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_URI} ^/my-custom-login [NC] RewriteCond %{REMOTE_ADDR} !^123\.456\.789\.000$ RewriteRule ^ - [R=404,L] </IfModule>Replace
123.456.789.000with your IP. - Use HTTPS: Ensure your site runs on HTTPS to encrypt login credentials.
Troubleshooting
If you encounter issues:
- 404 on Custom URL: Verify the
CUSTOM_LOGIN_SLUGmatches my-custom-login. - Logout Fails: Check the logout URL includes
_wpnonce(e.g., my-custom-login?action=logout&_wpnonce=abc123). - Redirects Persist: Disable plugins and clear caches. Test with a default theme.
- Locked Out: Use FTP to edit
functions.phpand comment out the code (wrap in/* */).
Enable debugging in wp-config.php to log errors:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
Check /wp-content/debug.log for details.
Conclusion
Changing your WordPress login URL to a custom slug like my-custom-login without plugins is a simple yet effective way to boost security. By following this guide, you’ve hidden wp-login.php and wp-admin, prevented unauthorized access, and ensured all login-related actions work flawlessly. Combine this with other security measures for a robust WordPress site.
Have questions or need help? Leave a comment below or contact us!