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.php
for login attempts. A custom URL makes it harder for them to find your login page. - Hide Admin Access: Blocking
wp-admin
with 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.php
andyour-site.com/wp-admin
while logged out. Both should return a 404 error. - Password Reset: Test
your-site.com/my-custom-login?action=lostpassword
to 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.php
andwp-admin
are inaccessible to unauthorized users, returning 404 errors. - Preventing Redirect Exposure: No redirects reveal the
my-custom-login
URL. - 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.000
with 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_SLUG
matches 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.php
and 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!