WordPress login security

Stop letting either a username or an email address unlock the same account

Restrict Login Identifier limits the WordPress login field to accept only a username or only an email address, closing off one of the two ways an attacker can try to guess their way in.

  • Choose username-only or email-only for the entire login form.
  • Removes the disallowed identifier's own core authentication callback.
  • A rejected value fails exactly like an unrecognized login normally would.
  • Application Passwords and other authentication paths stay untouched.
Login Form IdentifierRestrict Login Identifier
Username only
Email address only
Login restricted to usernameEmail address alone no longer works to sign in.
Active
Quick answer

What does Restrict Login Identifier do?

When the restrict_login_identifier module is active, TOWP_Restrict_Login_Identifier removes one of the two callbacks WordPress core registers on the authenticate filter at priority 20: wp_authenticate_username_password if the site restricts login to email addresses, or wp_authenticate_email_password if it restricts login to usernames. Because WordPress natively supports both identifier types through these two separate callbacks, removing one means the login form simply never attempts to match a submitted value against that identifier type. Consequently, a mismatched value fails to authenticate exactly the way an unrecognized username or email normally would, with no custom error handling required.

The "two ways in for every account" problem

WordPress accepts a username or an email, and never says which

Since the login field accepts both identifiers silently, every account effectively has two separate values worth guessing.

Every account effectively has two logins

By accepting both a username and an email address in the same field, WordPress gives an attacker two separate values to guess for every single account, not just one.

Email addresses are the easier half to collect

A site's email addresses often turn up in author bios, contact forms, comment notifications and countless other ordinary places, making them a far easier starting point than a username that was never published anywhere.

A dedicated WordPress solution

One identifier, chosen deliberately

Instead of adding a workaround on top of WordPress's own behavior, the module removes support for the identifier type a site doesn't want accepted.

Username-only, the default

Restrict the login field to usernames alone, closing off email address as a way to attempt a sign-in.

Or email-only, if that fits the site better

Restrict the field to email addresses instead, for sites where usernames aren't meant to be guessable login values at all.

Half the values an attacker has to guess

Whichever identifier gets disallowed, an attacker loses one of the two values that would otherwise work for every account on the site.

Verified feature set

A native removal, not a workaround

Every capability below is present in the supplied PHP class and its settings registration.

Email-only mode

Removes WordPress's own username authentication callback

wp_authenticate_username_password gets removed instead, so only an email address is ever checked against the login field.

wp_authenticate_username_passwordAlternate mode
No custom error handling

Fails exactly like an unrecognized login

Since the disallowed identifier's own callback never runs, a mismatched value fails authentication the same way WordPress already handles an unknown username or email.

Native failure pathNo custom logic
A native WordPress mechanism

Removes a core callback, doesn't fight it

The module removes one of WordPress's own two authentication callbacks rather than adding a new check on top of both.

remove_filterCore-native approach
Scoped to one authentication path

Application Passwords stay untouched

The restriction only affects the username/email password login form; other authentication paths, like Application Passwords, aren't touched.

Login form onlyApplication Passwords unaffected
One clear setting

A single choice for the whole site

The entire login form follows one consistent identifier rule, with no per-user or per-role exceptions to manage.

Site-wide settingNo exceptions to track
Practical use cases

Where restricting the identifier helps most

The module supports any site where one login identifier is clearly more exposed than the other.

Sites where email addresses are easy to find

Close off the easier-to-collect identifier on a site where staff or author email addresses already appear publicly.

Sites with non-obvious usernames

Restrict login to username specifically when usernames were deliberately chosen to be harder to guess than a published email address.

Standardizing login behavior for a client site

Give a client one clear, unambiguous way to log in, instead of leaving it open to either method without saying so.

Operational benefits

Fewer values to guess, nothing else affected

The module combines a genuine security narrowing with zero impact on unrelated authentication paths.

Fewer values to guess, for every accountAn attacker loses one of the two identifier values that would otherwise work against any account on the site.
Less value in a leaked email addressIf a site's email addresses are already public, restricting login to username specifically removes the payoff from having collected them.
A form that says what it wantsRestricting to one identifier also removes the ambiguity of a login field that never specifies which of the two it's expecting.
No impact on API-based authenticationApplication Passwords and other non-form authentication paths keep working exactly as before.
Performance behaviour

One filter removed, nothing added

The verified implementation makes the login check lighter, not heavier.

One filter removal, nothing else

The entire module is a single conditional remove_filter() call, adding no measurable overhead to the login process.

No additional checks on every login attempt

Since the disallowed identifier's callback is gone rather than intercepted, there's no extra validation step running on top of WordPress's own authentication flow.

Zero impact outside the login form

Nothing about this module runs anywhere except during the username/email/password authentication check itself.

Security implementation

A real reduction in guessable identifiers

The code closes off a genuine attack surface without touching anything else about login security.

01

Genuinely halves the guessable identifier space

Every account on the site can only be reached through one identifier instead of two, for every login attempt.

02

Closes off the easier-to-collect option specifically

Since email addresses tend to be more publicly discoverable than usernames, restricting to username removes the more exposed of the two paths.

03

Administrator-only configuration

Only an administrator with access to TheOneWP settings can choose which identifier the login form accepts.

04

No effect on password strength or other login protections

This module addresses only which identifier is accepted; it doesn't replace or interact with password policy, lockouts, or other login-security modules.

Verified compatibility

Built directly around WordPress's own authentication callbacks

The supplied code integrates through APIs present in WordPress core; this page makes no compatibility claim beyond the verified implementation.

Core authentication filter

authenticate, priority 20

The exact WordPress core filter and priority where both native identifier-checking callbacks get registered.

authenticatePriority 20
Username callback

wp_authenticate_username_password

The core function this module removes when a site restricts login to email addresses only.

wp_authenticate_username_passwordCore function
Email callback

wp_authenticate_email_password

The core function this module removes when a site restricts login to usernames only.

wp_authenticate_email_passwordCore function
Solution comparison

TheOneWP versus common alternatives

Compare the verified Restrict Login Identifier implementation with a typical hand-written login snippet.

CapabilityTheOneWP Restrict Login IdentifierOther common solutions
Restricting the login field to one identifier Removes WordPress's own native callback directlyOften intercepts and rejects values after the fact with custom code
Error handling for a disallowed identifier Falls back to WordPress's own native failure pathFrequently requires writing a custom error message
Scope Only the username/email login formA broad snippet can accidentally affect other authentication paths
Reliability Uses the same mechanism WordPress core relies on internallyA workaround built on top of both callbacks can behave inconsistently
Administration One setting, two clear choicesRequires a code snippet or a dedicated plugin
Recommended workflow

Restrict the identifier in four steps

Test both the allowed and the disallowed identifier before considering the change final.

01

Enable Restrict Login Identifier

Activate the module from the TheOneWP Login settings tab.

02

Choose username-only or email-only

Pick whichever identifier fits the site, based on which one is harder for an outsider to discover.

03

Test a login with the disallowed identifier

Confirm that attempting to log in with the disallowed identifier fails as expected.

04

Confirm the allowed identifier still works

Log in normally using the chosen identifier to confirm nothing about the working login path changed.

Best practices

Choose the identifier that's genuinely harder to find

The whole benefit depends on closing off the identifier an outsider could actually discover.

01

Choose the identifier that's harder to discover

If email addresses are already public on the site, username-only closes off the more exposed option.

02

Let users know which identifier to use

Since the login form itself won't say which identifier it expects, mention it wherever login instructions are shared.

03

Test before relying on it

Confirm both the allowed and the disallowed identifier behave as expected before considering the change complete.

04

Pair it with other login-security modules

This module addresses which identifier gets accepted; combine it with password and access controls for broader login protection.

Common mistakes

Avoid assumptions that reduce the benefit

A couple of details are easy to get backwards when configuring this for the first time.

Assuming Application Passwords are also restricted

This module only affects the username/email/password login form; other authentication paths keep working exactly as before.

Not telling users which identifier the form expects

Since the login form doesn't display which identifier it wants, users accustomed to the other one may need a heads-up.

Picking the identifier that's actually easier to find

Restricting to whichever identifier is already public defeats the purpose, so choose the one that's genuinely harder to discover.

Frequently asked questions

Restrict Login Identifier FAQ

These answers come directly from the verified class and its settings registration.

What does Restrict Login Identifier do?

It limits the WordPress login field to accept only a username or only an email address, instead of both, by removing WordPress's own callback for the disallowed type.

Does WordPress really accept both a username and an email by default?

Yes. WordPress core registers two separate callbacks on the authenticate filter, one checking usernames and one checking email addresses, and both run by default.

What happens if someone tries to log in with the disallowed identifier?

Since the module removes WordPress's own callback for that identifier type rather than adding a custom rejection, it fails to authenticate the same way an unrecognized username or email normally would.

Which mode should I choose, username-only or email-only?

Whichever identifier is harder for an outsider to discover; if email addresses are already public on the site, username-only closes off the more exposed option.

Does this affect Application Passwords or REST API authentication?

No. The restriction only applies to the username/email/password login form; other authentication paths stay untouched.

Will users be told which identifier the login form expects?

No. Since the form itself doesn't display which identifier it wants, it's worth communicating that separately if the change might surprise anyone.

Does this replace the need for a strong password policy?

No. It only addresses which identifier the login form accepts; password strength and other login protections remain separate concerns.

Can I switch between username-only and email-only later?

Yes. The mode can change at any time from the same setting.

Does restricting the identifier slow down the login process?

No. Since the module removes one existing check rather than adding a new one, there's no additional processing on each login attempt.

Who can change which identifier the login form accepts?

Only an administrator with access to the TheOneWP settings screen.

Stop giving attackers two ways into every account.Accept just one login identifier, deliberately.

Use Restrict Login Identifier to limit the login form to username-only or email-only, closing off half the values an attacker has to guess.