Subtle diagonal pinstripe pattern in light grey and cream, giving an impression of printed editorial paper

Implementing two-factor authentication in WordPress with TOTP

Two-factor authentication (2FA) strengthens a WordPress login by requiring a second proof of possession, even if the password has leaked. For site administrators, it can protect theme editing, plugin installation, user management and WooCommerce settings. Apply it first to accounts that can install plugins or change payment settings, because those privileges can turn a compromised login into a site-wide incident. The second factor should be easy for legitimate users to provide and difficult for an attacker to reproduce or steal. It is a security control, not a replacement for patching, least privilege or backups.

TOTP means time-based one-time password. An authenticator app and the WordPress site share a secret, then derive a short numeric code from the current time, usually a six-digit code that rotates every 30 seconds. Because the code changes quickly and never travels like SMS, it reduces some account-takeover risks, although phishing-resistant passkeys or security keys can offer stronger protection where supported.

Implementing TOTP in WordPress means choosing where verification happens, enrolling people without locking them out, protecting the shared secrets and defining a safe recovery process. It also means deciding which roles must use it and documenting who can authorise an exception. For a WooCommerce site, test staff access and customer account access separately. A measured rollout is more reliable than switching on a blanket requirement immediately after the plugin is installed.

Compare implementation approaches

There are three practical routes. A maintained WordPress plugin is usually quickest, a hosted identity platform gives central control, and custom code gives full control at the highest maintenance cost. The right choice depends on who administers the site, how many users need access and whether the organisation already manages authentication through another service. Compare the operational burden as well as setup time.

Approach Best fit Benefits Main trade-off
Maintained WordPress plugin Most site owners and small teams Fast setup, tested TOTP handling, recovery tools and role controls Requires careful configuration and regular updates
Hosted identity provider or SSO Larger organisations with central identity Central policies, authentication methods and audit trails Adds cost and another dependency
Custom plugin or service Developers with unusual requirements Full control over enrolment and user experience You own secret storage, replay protection, testing and support

Most Australian WordPress projects fit the plugin route. A Sydney online retailer, a Melbourne web studio and a Brisbane wholesaler may all use the same core stack, but their needs differ: one may have a small admin team, another may run client sites, and another may depend on WooCommerce order access. A plugin keeps these needs local and avoids introducing another vendor or long-lived SSO dependency. If the site already uses company single sign-on, extending that service may be cleaner than maintaining a second credential system.

For organisations covered by the Privacy Act 1988, Australian Privacy Principle 11 requires reasonable security arrangements for personal information. Time-based one-time passwords can support that goal by protecting account access, but they do not establish compliance on their own. The Australian Cyber Security Centre also recommends strong authentication as a practical control for systems that can change business-critical data, including websites that hold customer records or process orders.

Install and configure the authentication plugin

Begin in staging, not on the live administrator account. Back up the database and wp-config.php, record the current login method and test in a second browser or private window. Compare maintained options such as the Two Factor and Wordfence Login Security plugins, checking recent releases, support quality, TOTP support, recovery-code handling and compatibility with your WordPress and PHP versions. Test the chosen plugin with a non-privileged account first.

After installation, configure the token length, period and accepted clock drift. Six digits and a 30-second interval give broad compatibility with Google Authenticator, Microsoft Authenticator, 1Password and similar authenticator software. A one-step tolerance can accept the adjacent code when a phone clock is slightly behind, but excessive tolerance widens the guessing window. Keep HTTPS enabled because the enrolment secret and session cookies must not cross an unencrypted connection.

Set access policy by role rather than by habit. Require it for administrators, editors, plugin editors and WooCommerce shop managers first, then assess other roles. Avoid forcing a popup on every public or customer request, as that can damage checkout conversion. Also leave cron, application-password and REST API authentication intact; TOTP is designed for interactive sign-in and should not silently break scheduled tasks, mobile clients or integrations. Recheck the policy after each major release.

Enrol users and prepare recovery

Enrolment begins from the user profile in a plugin-provided screen, although some plugins also provide a dedicated administration page. Open Users, then All Users, select the account and follow the plugin's two-factor enrolment link. The user scans a QR code with an authenticator app or types the Base32 shared secret manually. The QR normally encodes an otpauth URI containing the issuer, account label, algorithm, digit count and secret. Use a clear Australian brand and a unique account label so staff do not select the wrong entry.

Recovery needs planning before enrolment. Generate one-time backup or recovery codes, store them in an approved password manager or a sealed offline process, and explain that each code should be used once. A spare hardware token can be recorded for senior administrators, but it must not share an account label without clear custody rules. The shared secret is effectively a reusable password, so it should not be pasted into email, chat or a screenshot. Limit who can view or reset another user's second factor.

Roll out in stages and keep at least one test account that uses 2FA. Ask each enrollee to enter a code immediately, then test the recovery route before marking the account complete. Codes are based on Unix time rather than local civil time, so daylight-saving changes in New South Wales, Victoria and South Australia do not alter the secret. An incorrect device clock can still cause rejection, so enable automatic time synchronisation and provide a short clock-check step in the support guide.

Verify codes and protect secrets

Test with real devices and ordinary mobile networks, not only the administrator's desk. A successful code should be accepted once per time step, expired codes should fail, and repeated guesses should receive a rate limit or temporary lockout. Check what happens after a password change, role change, session renewal or plugin update. Recovery should be impossible to trigger from an unauthenticated request, and support staff should verify identity without relying on the second factor they are trying to bypass.

A production TOTP service should encrypt each shared secret at rest with authenticated encryption, keep the encryption key outside the database and restrict access to secret-bearing code. It should use constant-time comparison, avoid logging submitted codes and apply both per-account and per-address throttles. Prevent replay by recording recently accepted counters, and keep failure messages generic so attackers cannot enumerate usernames. Session cookies need Secure, HttpOnly and appropriate SameSite attributes. Test that an administrator can revoke active sessions without deleting valid enrolments.

If a custom plugin is unavoidable, use a maintained RFC 6238 library instead of writing the HMAC and truncation logic yourself. Generate codes from a decoded Base32 secret, a Unix-time counter and the configured interval, then verify against an allowed window. Integrate this check after WordPress has validated the primary credential, protect the form with a nonce and make sure failures cannot create an open redirect or reveal whether a username exists. Extensive unit and integration tests are part of the implementation, especially around time boundaries and concurrent requests.

Operate the system after launch

Treat the second factor as a maintained service. Update WordPress core, the authentication plugin and PHP regularly, and retest enrolment after major upgrades because libraries, QR codes or recovery formats can change. Remove access promptly when staff leave, rotate a shared secret after suspected disclosure, and rehearse restoring both the site and authenticator access from backup. Keep one audited break-glass account in escrow with a long, unique password and disabled inbox notifications. Review its use after every incident.

Australian agencies often support WooCommerce stores on .com.au domains under support agreements priced in AUD, with coverage during local business hours. Their runbooks should name a contact, escalation path and maximum time to restore access for administrators and payment staff. Customer-facing 2FA can be offered for high-value accounts, but a simpler support process may be better for ordinary shoppers. Record the agreed Australian Eastern and Western Time windows in handover documentation so teams in different cities interpret deadlines consistently.

Monitor adoption and failures without collecting usable one-time passwords. Useful signals include enrolled administrators, recovery-code use, repeated invalid codes and lockouts caused by clock drift. Review the enrolment list after each WordPress or plugin update, and rehearse lost-phone recovery with a non-production user. If a session or secret may be compromised, revoke active sessions, invalidate the secret, issue fresh recovery codes and follow relevant ACSC incident guidance. A tested TOTP rollout then becomes a measurable part of WordPress access control rather than an extra screen nobody trusts.