Two-factor login for WordPress: app codes, passkeys and how not to lock yourself out
How the second login step works on WordPress, how an authenticator code differs from a passkey, how to set it up for free, and what to prepare before someone loses their phone.
Out of the box, WordPress asks for a user name and a password and nothing else. Two-factor login adds a second step: after the password, you type a code from an app on your phone or confirm the sign-in with a passkey. A password on its own then no longer opens the dashboard. You can set it up for free with a plugin from the WordPress.org directory, and it takes a few minutes per account.
This guide covers the kinds of second step, how to judge them, how to roll it out on a site with several users, and what to have ready before someone loses a phone.
Why bother if the password is strong
A strong password stops guessing. It does not help in three common cases:
- the same password was used on another service, and that service leaked it,
- someone typed it into a fake login page linked from an email,
- it was saved in the browser on a computer that other people use.
In each case someone else knows the password. With a second step, knowing it is not enough to get into the dashboard.
Three kinds of second step
A code from an authenticator app (TOTP). During set-up you scan a QR code with an app on your phone. From then on the app shows a six-digit code that changes every 30 seconds. The phone needs no connection for this: the code is computed from a stored secret and the current time. Every common authenticator app supports it.
The weak spot: a code can be typed into a fake login page just like a password, and an attacker who is quick can use it before it expires.
A code sent by email. Convenient, since there is no app to install. It is only as strong as the mailbox, though. If the mailbox uses the same password as WordPress, the second step adds little.
A passkey (the WebAuthn standard). Instead of typing a code, you confirm with a fingerprint, your face, the phone's PIN or a USB security key. The browser ties each passkey to the domain it was created on. On a look-alike page under another domain, the browser will not offer the passkey at all, so there is nothing to steal. Passkeys need the site to run over HTTPS.
Can you do it without a paid plugin
Yes. The WordPress.org Advanced Administration handbook (as updated on 14 October 2026) points to plugins in the directory for two-step login, since WordPress does not include it. Several free plugins do it. One example: on 19 October 2026 the WordPress.org page of the Two Factor plugin (by WordPress.org, version 0.17.0) listed authenticator app codes, email codes and backup codes, and described WebAuthn passkey support as a separate add-on.
Before you install one, look for four things in its description:
- Which second-step methods it supports, and whether an authenticator app is one of them.
- Whether it gives you recovery codes for a lost phone.
- Whether someone with server access can turn off the second step for an account that got locked out.
- Whether it can require the second step for chosen roles.
Rolling it out without locking anyone out
- Start with your own account. A good plugin asks for codes only after you have typed a working code during set-up. That confirms the app produces the right codes before anything depends on them.
- Keep the recovery codes off the phone. A password manager is a good place. Codes stored on the same phone as the app are lost with it.
- Decide who rescues a locked account. Find out who has server access (you, your developer, your host) and how they turn off the second step for one account there. Write it down before you need it.
- Require it for roles with power. Administrators, editors and shop managers can change the site or see customer data. Give them a few days to set it up, and tell them by email first.
- Move apps to application passwords. The WordPress mobile app, or a tool that publishes through the REST API, cannot show a code screen. WordPress has application passwords for this: in the user profile you create a separate password for one tool, and you can revoke it at any time.
- End the old sessions. WordPress keeps you signed in for two days, or 14 days with "Remember Me" ticked. After turning on the second step, sign the account out on its other devices so old sessions do not skip the new rule.
Things to watch for
- The phone's clock. App codes depend on the time. If codes suddenly stop working, check that the phone sets its time automatically.
- A new domain. A passkey works for the domain it was created on. After moving the site to a new address you will need to add a new one, so keep the app or the recovery codes as a second way in.
- Someone leaving. Delete their account or take away the role. Switching off their phone does not close their account.
- It protects the login and nothing else. A hole in an outdated plugin needs no login. Updates still matter, as the article on outdated WordPress plugins explains.
How Ensomedia Security does it
Ensomedia Security is a free plugin in the WordPress.org directory that I built for ShieldWave. Everything in it works the same without a ShieldWave account. The facts, from its listing and its code:
- the second step is a code from an authenticator app (TOTP), and you get ten recovery codes at set-up,
- the WP-CLI command
wp shieldwave two-factor disable <user>turns it off for one account, so nobody is locked out for good, - apps sign in with an application password,
- you can require two-factor login for the roles you choose, with 0 to 30 days (7 by default) to set it up,
- passkeys (WebAuthn) work as the second step after the password, and the password is still needed. They need HTTPS and the OpenSSL extension in PHP,
- because the browser ties a passkey to the site's domain, a look-alike login page gets the password at most, never the second step,
- adding or removing a passkey asks for the password or a current code first, and the account owner gets an email when a passkey is added,
- the sessions section shows where the account is signed in, signs you out everywhere else or signs out every user, and sets how long an administrator's session lasts,
- login protection limits failed logins per address (5 by default, then a cooldown) and per user name across all addresses (20 an hour by default). Locks are temporary, and trusted addresses are never locked.
It is not a full web application firewall, and it does not clean malware out of files. The plugin's page lists what each optional service sends, and the screen by screen guide walks through the settings.
A short list for today
- Turn on the second step for your own administrator account and put the recovery codes in a password manager.
- Find out how to turn it off for one account when someone loses a phone.
- Require it for every role that can change the site, with a few days to set it up.
- Give tools and apps their own application passwords.
- Sign your account out of devices you no longer use.
Check your site from the outside. Enter your address at shieldwave.io. It takes about 90 seconds and needs no password and no plugin.