WP Manifestindependent plugin directory
manifest / users / rep-magic-login

REP Magic Login (Passwordless Email Link)

Passwordless WordPress login via one-time emailed magic links. Single-use, hashed, expiring tokens; intentionally bypasses 2FA by design.

★ 0stars

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/abchiaravalle/rep-magic-login/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

A single-file WordPress plugin that lets users log in via a one-time, short-lived link emailed to their on-file address — no password required. Built for users who struggle with passwords.

How it works

  1. On wp-login.php, a user clicks "Can't use your password? Email me a login link".
  2. They enter their username or email. A 256-bit token is generated; only its SHA-256 hash is stored (update_user_meta). The raw token is emailed as a link to the account's on-file address — never to whatever address they type in the form.
  3. Clicking the link opens a small confirm page that auto-submits a POST to actually authenticate. The token is deleted from the database before validation (so it can never be replayed), then compared with hash_equals() (constant-time), then the user is logged in via wp_set_auth_cookie().
  4. The link works once and expires in 15 minutes.

Security design

  • 256-bit tokens, only SHA-256 hashes ever touch the database.
  • Single-use: the token record is deleted before validation, so replay is impossible even if the link leaks after use.
  • 15-minute expiry.
  • Two-step consume (GET renders, POST authenticates): the emailed link is a plain GET, but visiting it does not consume the token — it renders a page that auto-submits a POST. This exists specifically so automated email-security link scanners (Microsoft 365 Safe Links, Proofpoint, Mimecast, etc.), which prefetch links server-side before a human opens them, can't silently burn the token.
  • No user enumeration: the request-a-link response is identical (body and, as of v1.1.0, padded timing) whether or not the submitted username/email resolves to a real account.
  • Per-user AND per-IP rate limiting: 1 request/min per resolved account, plus an IP-level cap so guessing usernames that don't exist is still throttled.
  • CSRF protection via WordPress nonces on the request form.
  • Failed/expired/invalid token attempts fire wp_login_failed, so security plugins (Wordfence, etc.) can see and alert on them.
  • Administrators are excluded from magic login by default (filterable) — see the intentional trade-off below.

Intentional trade-off: this bypasses 2FA

Authentication happens via wp_set_current_user() / wp_set_auth_cookie() directly rather than through wp_signon()/wp_authenticate, which means any 2FA plugin's normal auth-chain hooks are not invoked. This is deliberate: for the target audience — people who struggle with passwords — possession of the emailed link is the second factor. If you need 2FA enforced even for magic-login users, don't enable this plugin for those accounts, or use the rep_magic_login_allowed_user filter to exclude them.

Filters

// Control which users may use magic login. Receives (bool $allowed, WP_User $user).
// Default: everyone except administrators.
add_filter( 'rep_magic_login_allowed_user', function( $allowed, $user ) {
    return $allowed;
}, 10, 2 );

// Control the post-login redirect. Receives (string $url, WP_User $user).
add_filter( 'rep_magic_login_redirect', function( $url, $user ) {
    return $url;
}, 10, 2 );

Requirements

  • WordPress with a working outbound mailer (e.g. WP Mail SMTP) — magic links are useless if wp_mail() can't actually deliver.
  • PHP random_bytes() (PHP 7+, built in).

Installation

Drop rep-magic-login.php into wp-content/plugins/rep-magic-login/ and activate it from the WordPress admin, or via WP-CLI:

wp plugin activate rep-magic-login

Known limitations

  • Corporate email link-scanners that execute JavaScript (rare, but exists) could still trigger the auto-submit on the confirm page. The two-step design blocks the common case (server-side prefetchers that fetch the URL without rendering/executing anything), not every conceivable scanner.
  • Timing-based padding on the "request a link" response reduces but does not perfectly eliminate a timing side-channel for enumeration on unusually slow mail infrastructure.
  • No built-in CAPTCHA/honeypot on the request form; the per-IP rate limit is the primary defense against automated abuse at volume.

License

GPL-2.0-or-later