---
term: 'Multi-Factor Authentication (MFA)'
seoTitle: 'Multi-Factor Authentication (MFA): Methods Ranked, TOTP, Passkeys'
headline: 'What is Multi-Factor Authentication (MFA)?'
slug: multi-factor-authentication-mfa
category: auth-security
shortDefinition: 'Multi-factor authentication is a login control requiring two or more different kinds of proof — something you know, have, or are.'
relatedTerms:
  - passwordless-authentication
  - oauth-2-social-login
  - identity-access-management-iam
  - json-web-token-jwt
contrastsWith:
  - passwordless-authentication
aboutTerms:
  - 'TOTP'
  - 'Phishing-Resistant MFA'
  - 'Passkeys'
  - 'MFA Fatigue'
faq:
  - question: 'What is MFA in simple terms?'
    answer: 'Sign-in that requires two or more different kinds of proof — say, a password plus a code from your phone — so a stolen password alone opens nothing. The proofs must come from different categories: a password plus a security question is still one factor, twice.'
  - question: 'What is the difference between MFA and 2FA?'
    answer: 'Scope. 2FA means exactly two factors; MFA means two or more. All 2FA is MFA, and in practice most MFA deployments are 2FA. The number matters less than the quality — two phishing-resistant factors beat three phishable ones.'
  - question: 'What are the three factors of authentication?'
    answer: 'Something you know (password, PIN), something you have (phone, hardware key), something you are (fingerprint, face). Location and behavior appear as supplementary signals, but they drive adaptive, risk-based checks rather than standing in as factors on their own.'
  - question: 'Is SMS two-factor authentication safe?'
    answer: 'Better than a password alone, but the weakest common method: SIM-swapping, telecom-protocol interception, and ordinary phishing all defeat it. Standards bodies have restricted it for years, and current government guidance is blunt — don''t use SMS as a second factor where anything stronger is available.'
  - question: 'How does a TOTP authenticator app work?'
    answer: 'At enrollment the QR code hands the app a shared secret. From then on, app and server independently compute a code from that secret and the current 30-second time window; matching codes prove possession. Entirely offline — no network, no account with the app''s maker, just synchronized clocks and math.'
  - question: 'Do passkeys replace MFA?'
    answer: 'For most accounts, effectively yes: a passkey is multi-factor in one gesture — possession of the device plus the biometric or PIN that unlocks it — and phishing-resistant besides, since the signature only works on the genuine site. High-assurance contexts may still layer a separate factor on top.'
  - question: 'What is phishing-resistant MFA?'
    answer: 'MFA that cannot be relayed through a fake site. Codes and push approvals can be proxied in real time; public-key methods — passkeys and hardware security keys under WebAuthn — bind the response cryptographically to the real domain, so a look-alike site gets a signature that is worthless anywhere else.'
  - question: 'What is an MFA fatigue attack?'
    answer: 'Push bombing: an attacker with a stolen password triggers approval prompts until the exhausted victim taps yes — the method behind several famous breaches. Mitigations, in order: number matching on prompts, rate limits on attempts, and ultimately moving to methods with nothing to approve.'
  - question: 'How effective is MFA really?'
    answer: 'Near-total against automated credential-stuffing and password-spraying — the widely cited ninety-nine-percent figures come from measuring exactly those attacks. Against targeted phishing with real-time proxy kits, code- and push-based MFA can be bypassed; only the phishing-resistant methods hold. Both claims are true; know which one your threat model needs.'
  - question: 'What are backup codes for?'
    answer: 'Single-use recovery codes issued at enrollment, for the day the phone is lost. Store them offline. Recovery is MFA''s weakest link — attackers deliberately target reset flows and help desks — so recovery should demand assurance equal to or higher than the login it overrides.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'NIST SP 800-63B — Digital Identity Guidelines: Authentication'
    url: 'https://pages.nist.gov/800-63-3/sp800-63b.html'
  - name: 'RFC 6238 — TOTP: Time-Based One-Time Password Algorithm'
    url: 'https://datatracker.ietf.org/doc/html/rfc6238'
  - name: 'CISA — Implementing Phishing-Resistant MFA'
    url: 'https://www.cisa.gov/sites/default/files/publications/fact-sheet-implementing-phishing-resistant-mfa-508c.pdf'
  - name: 'W3C Web Authentication (WebAuthn)'
    url: 'https://www.w3.org/TR/webauthn-2/'
  - name: 'Multi-factor authentication — Wikipedia'
    url: 'https://en.wikipedia.org/wiki/Multi-factor_authentication'
cta:
  title: 'Step-up auth without building it'
  text: 'Back4app''s MFA adapter adds TOTP to your login flow with a config block — enrollment, verification windows, and recovery codes handled by the platform, on top of sessions it can revoke instantly.'
  linkText: 'Start building free'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-07-27'
translationKey: multi-factor-authentication-mfa
---

**Multi-factor authentication is a login control requiring two or more different kinds of proof — something you know, have, or are.** The word *different* is load-bearing and widely fumbled: a password plus a security question is two proofs from one category — knowledge — and therefore not MFA at all. The point is combinatorial: a phished password doesn't hold your phone; a stolen phone doesn't know your PIN; each factor's theft leaves the attacker one category short.

## Key takeaways

| Question | Answer |
| --- | --- |
| The factors | Know (password) · have (device, key) · are (biometric) — from *different* categories |
| MFA vs. 2FA | 2FA = exactly two; MFA = two or more; quality beats quantity |
| The ranking | SMS < TOTP < push < push + number match < **passkeys / security keys** |
| The dividing line | Phishing-resistance: codes can be relayed; origin-bound cryptography can't |
| The weak link | Recovery — reset flows must be as strong as the login they override |

## How TOTP actually works

The authenticator app, demystified — no ranking page explains the machinery ([RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238)):

```text
Enrollment   QR code = otpauth://totp/app:ada?secret=JBSWY3DP…
             → the app now shares a Base32 SECRET with the server

Every 30 s   both sides compute, independently and offline:
             code = truncate( HMAC-SHA1( secret, floor(unix_time / 30) ) ) % 10⁶

Login        you type the app's 6 digits; the server computes its own,
             accepts ±1 time window for clock drift → match = possession proven
```

Wiring that into an app's login flow:

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// TOTP step-up with the Parse Server mfa auth adapter
// Enroll: prove possession by sending one valid code with the secret
await currentUser.save({
  authData: { mfa: { secret: totpSecret, token: codeFromApp } },
});
// server returns single-use recovery codes — show once, store nowhere

// Log in afterwards: password + the current 6-digit code
const user = await Parse.User.logIn('ada', password, {
  authData: { mfa: { token: codeFromApp } },
});
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// TOTP step-up with the Parse Server mfa auth adapter
// Enroll: prove possession by sending one valid code with the secret
currentUser.set('authData', {
  'mfa': {'secret': totpSecret, 'token': codeFromApp},
});
await currentUser.save();
// server returns single-use recovery codes — show once, store nowhere

// Log in afterwards: password + the current 6-digit code
final user = ParseUser('ada', password, null)
  ..set('authData', {'mfa': {'token': codeFromApp}});
await user.login();
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// TOTP step-up with the Parse Server mfa auth adapter
// Enroll: prove possession by sending one valid code with the secret
let enrolled = try await currentUser.link("mfa",
    authData: ["secret": totpSecret, "token": codeFromApp])
// server returns single-use recovery codes — show once, store nowhere

// Log in afterwards: password + the current 6-digit code
let user = try await User.login("ada", password: password,
    authData: ["mfa": ["token": codeFromApp]])
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// TOTP step-up with the Parse Server mfa auth adapter
// Enroll: prove possession by sending one valid code with the secret
val enroll = mapOf("secret" to totpSecret, "token" to codeFromApp)
ParseUser.getCurrentUser().linkWithInBackground("mfa", enroll)
// server returns single-use recovery codes — show once, store nowhere

// Log in afterwards: password + the current 6-digit code
val authData = mapOf("token" to codeFromApp)
ParseUser.logInWithInBackground("mfa", authData) // paired with the password check
```

## MFA vs. 2FA

| | 2FA | MFA |
| --- | --- | --- |
| Factors | Exactly two | Two or more |
| Relationship | A subset of MFA | The umbrella term |
| In practice | What most deployments actually are | What most deployments are called |

One table settles it; the sharper question is *which* factors — because the security ceiling is set not by how many proofs you stack but by whether any of them can be phished.

## The method ranking, honestly

The comparison the [CISA guidance](https://www.cisa.gov/sites/default/files/publications/fact-sheet-implementing-phishing-resistant-mfa-508c.pdf) publishes and vendor explainers won't — which attacks defeat which methods:

| Method | Phishing / real-time proxy | SIM swap | Push bombing | Offline? | Verdict |
| --- | --- | --- | --- | --- | --- |
| SMS / voice codes | Defeated | **Defeated** | n/a | No | Last resort — [restricted by NIST](https://pages.nist.gov/800-63-3/sp800-63b.html) |
| Email codes | Defeated | Safe | n/a | No | Inherits your inbox's security |
| TOTP app | Defeated | Safe | n/a | **Yes** | The solid baseline |
| Push approval | Defeated | Safe | **Defeated** | No | Convenient, bombable |
| Push + number matching | Defeated | Safe | Resistant | No | Patched convenience |
| **Passkeys / security keys** | **Resistant** | Safe | n/a | Yes | The gold standard ([WebAuthn](https://www.w3.org/TR/webauthn-2/)) |

The pattern in the leftmost column is the modern story: *every* code and approval can be relayed through a phishing proxy; only origin-bound cryptography survives contact with a fake login page.

## The attacks, in plain language

```mermaid
flowchart LR
  accTitle: Adversary-in-the-middle phishing proxy relaying MFA
  accDescr: The victim enters credentials and a one-time code on a fake site, which relays them in real time to the genuine site, receives a valid session, and hands the attacker the session cookie. Passkeys defeat this because their signature is bound to the genuine domain and fails on the fake one.
  V["Victim"] -->|"password + OTP code"| F["Fake login page<br/>(proxy kit)"]
  F -->|"relays in real time"| R["Real site"]
  R -->|"valid session cookie"| F
  F -->|"session handed over"| A["Attacker logged in"]
  P["Passkey attempt on fake page"] -.->|"signature bound to real domain<br/>→ worthless to the proxy"| X["Fails"]
```

**Adversary-in-the-middle phishing:** open-source proxy kits sit between victim and real site, relaying password *and* one-time code live, then keep the resulting session cookie — MFA "passed," account lost. **Push bombing:** with a stolen password, spam approval prompts until fatigue wins one tap; number matching (type the digits shown on screen) removes the mindless-approve path. **SIM swapping:** persuade a carrier to move the victim's number, then receive their SMS codes — the attack that put SMS at the bottom of the table. The common thread: these defeat *factors that can be told to someone*; they all break against factors that only speak cryptographically to the genuine origin.

## The recovery problem

Every MFA rollout creates a second door: what happens when the phone is lost? Backup codes — single-use, generated at enrollment, stored offline — are the standard answer; account recovery flows are the dangerous one. If a help-desk call or an email reset can remove MFA, the attacker calls the help desk — the technique behind headline breaches — and your strongest control is overridden by your weakest process. The rule: **recovery must demand assurance equal to or higher than the login it replaces** — multiple enrolled methods, step-up verification for resets, and MFA removal treated as a privileged, logged, alert-raising event.

## How effective is MFA, really?

Two true claims, often confused. Against *automated* attacks — credential stuffing, password spraying — MFA is near-total: the famous ninety-nine-percent figures come from large-scale sign-in telemetry measuring exactly those, and a peer-reviewed follow-up found ~99% compromise reduction in the same scope. Against *targeted* phishing with real-time proxies, code- and push-based MFA is demonstrably bypassable, which is why critics put all-attacks effectiveness far lower and why agencies now push phishing-resistant methods specifically. The honest synthesis: any MFA ends the era of the password being enough; only passkey-class MFA ends phishing. Deploy *some* MFA everywhere, and phishing-resistant MFA wherever the stakes justify the enrollment friction.

## Common use cases

- **Protecting account issuance** — MFA guards the moment [sessions and tokens](/glossary/json-web-token-jwt/) are minted; everything downstream trusts that gate.
- **Step-up for sensitive actions** — re-prompt at payment, deletion, or key export, not just at login.
- **Admin and privileged accounts** — where MFA should be mandatory and phishing-resistant, no exceptions.
- **Compliance regimes** — payment, health, and government frameworks increasingly require MFA outright.
- **Complementing [social login](/glossary/oauth-2-social-login/)** — inherited from the identity provider, or enforced locally for high-value actions.

## Which MFA method should you offer? A decision matrix

| Situation | Offer |
| --- | --- |
| General user base, broad devices | TOTP as baseline + passkeys as the promoted path |
| High-value or admin accounts | Phishing-resistant only — passkeys / security keys |
| Users without smartphones | Hardware keys or printed backup codes, not SMS-by-default |
| Legacy population, nothing else viable | SMS — eyes open, as a floor not a norm |
| Sensitive in-app actions | Step-up re-authentication, whatever the login factor |
| Recovery design | Two enrolled methods minimum + offline codes |

## Limitations and trade-offs

- **Friction is real and measurable.** Every prompt costs conversion and support tickets; adaptive, risk-based prompting spends friction where risk lives.
- **Phishable MFA buys less than it seems.** Against a targeted proxy attack, codes and pushes fall; treat them as automation-stoppers, not phishing armor.
- **The phone is a single point of failure.** Device loss without recovery planning becomes lockout at scale — enrollment UX must plant backup methods on day one.
- **Recovery flows invert the math.** A weak reset path silently caps your whole scheme at its own strength.
- **Enrollment is the adoption cliff.** Mandates without smooth QR flows and clear fallbacks generate resistance; the best scheme is the one users actually complete.

## MFA on Back4app

Back4app is an open-source Backend-as-a-Service (BaaS) platform that combines a managed database, auto-generated REST and GraphQL APIs, authentication, file storage, and Cloud Code serverless functions. TOTP arrives as configuration, not construction: Back4app's `mfa` auth adapter turns on time-based codes with a config block — digits, period, and algorithm tunable — and the code tabs show the whole client story: enrollment proves possession by pairing the shared secret with one valid code, the server issues single-use recovery codes, and subsequent logins pair the password with the current six digits. Because the platform's sessions are revocable server-side, the surrounding hygiene holds too: an MFA change can terminate other sessions immediately, and Cloud Code triggers are the natural place to log enrollment events and gate MFA removal behind step-up checks — the recovery discipline this article argues for, expressed in a few functions.
