Key takeaways
- Offer passkeys and biometrics first; fall back to TOTP and OTP.
- Ask for a second factor based on risk, not on every login.
- Recovery flows are part of security — design them as carefully as sign-in.
- Measure enrolment, completion and lockouts, not just whether MFA is switched on.
Multi-factor authentication (MFA) stops the vast majority of account-takeover attacks. Stolen passwords become far less useful when an attacker also needs your phone, your fingerprint or a hardware key.
Yet people still turn MFA off, skip enrolment or choose the weakest option available, because it gets in the way. Good MFA is as much a design problem as a security one. This article collects what we've learned designing authentication flows, and what's shaping the Flutter MFA plugin we're building.
Why people resist MFA
Before designing anything, it helps to understand the objections:
- Friction: an extra step at every login, often at the worst possible moment.
- Fear of lockout: "What happens if I lose my phone?" is a reasonable worry.
- Confusing set-up: QR codes, authenticator apps and six-digit codes are unfamiliar to many people.
- Poor timing: being forced to enrol before you've even seen the product.
- Slow or unreliable codes: SMS that arrives late, or not at all, abroad.
Each objection has a design answer. The goal is MFA that people barely notice, until the day it saves their account.
Know your factors
Not all second factors are equal. They differ in security, convenience and cost:
| Factor | Phishing-resistant | Convenience | Notes |
|---|---|---|---|
| Passkeys (FIDO2/WebAuthn) | Yes | Excellent — one tap or glance | Synced across devices by Apple, Google and password managers |
| Device biometrics | Yes, when bound to the device | Excellent | Usually unlocks a passkey or stored key |
| Hardware security keys | Yes | Good | Ideal for admins and high-risk roles |
| Authenticator apps (TOTP) | No | Good | Works offline; codes can still be phished |
| Push approval | Partly | Very good | Use number matching to stop "push fatigue" attacks |
| Email one-time codes | No | Fair | Only as strong as the email account |
| SMS one-time codes | No | Fair | Vulnerable to SIM swapping and interception |
The pattern is encouraging: the strongest options are also the easiest to use.
Start with the strongest, easiest factor
Passkeys and biometrics are both the most secure and the least annoying option. A passkey replaces "type a code from another app" with "look at your phone" or "touch the sensor". It can't be typed into a fake website, because it's bound to the real domain.
Lead with them during enrolment, and present fallbacks as fallbacks:
- Default: "Use Face ID / fingerprint / your device to sign in" (passkey).
- Alternative: "Use an authenticator app."
- Last resort: "Send me a code" (SMS or email).
Ordering matters. When every option is presented equally, many people pick SMS simply because it's familiar.
Enrol at the right moment
Forcing MFA set-up on the first screen of a new account is a common mistake. People haven't seen any value yet, so the request feels like an obstacle.
Better moments to ask:
- After the first meaningful success: the first project created, order placed or document saved.
- Before the first sensitive action: adding a payment method, inviting team members, exporting data.
- When the stakes rise: becoming an admin, connecting a bank account.
Explain why in one sentence: "Protect your account and your team's data. Takes 30 seconds." Then make the strongest option one tap.
Ask at the right moments
Prompting for a second factor on every login trains people to resent it. Instead, use risk-based or step-up authentication and ask when risk is higher:
- A new device, browser or location.
- A sensitive action, like changing payment details, email or password.
- A long time since the last verification.
- Unusual behaviour, such as many failed attempts or impossible travel between logins.
On a trusted device in a familiar context, a remembered session or a passkey is enough. That keeps everyday use smooth and concentrates friction where it matters.
Security that people work around is not security.
Make codes painless
When people do use one-time codes, small details make a big difference:
- Autofill: on the web, mark the input with
autocomplete="one-time-code"so phones can fill SMS codes automatically. - One field, not six boxes: split boxes look neat but break pasting, autofill and screen readers.
- Numeric keyboard: use
inputmode="numeric"so mobile users get the right keypad. - Generous time windows: allow for slow typists and assistive technology, and say how long a code is valid.
- Clear resend: show when a new code can be requested, and invalidate old ones.
<label for="otp">Verification code</label>
<input
id="otp"
name="otp"
inputmode="numeric"
autocomplete="one-time-code"
pattern="[0-9]*"
/>Fight push fatigue
Push approvals ("Is this you signing in? Approve / Deny") are convenient, but attackers exploit them by sending repeated prompts until a tired user taps Approve.
Defences that keep push usable:
- Number matching: the login screen shows a number the user must enter or select in the app.
- Context: show the location, device and app requesting access.
- Rate limits: stop sending prompts after a few denials, and alert the user.
Design recovery like a first-class flow
Lost phones are inevitable. If recovery is painful, people either avoid MFA or flood your support team. If recovery is weak, it becomes the easiest way in for attackers.
A balanced recovery design:
- Require two methods at enrolment. For example a passkey plus backup codes, or two registered devices.
- Make backup codes easy to save. Offer download, copy and print, and ask the user to confirm they've stored them.
- Self-service first. Let people use a backup method to remove a lost device and add a new one.
- A secure human path. Support staff need a documented identity-verification process, and the power to reset MFA should be audited.
- Notify on changes. Email the user whenever factors are added, removed or reset, so they can react if it wasn't them.
Accessibility is part of usability
Authentication must work for everyone:
- don't rely on a single biometric; offer alternatives
- avoid strict time limits, or let users extend them
- ensure codes and QR set-up steps work with screen readers, including a text "setup key" alternative to scanning a QR code
- write clear, specific error messages ("That code has expired. We've sent a new one.")
WCAG 2.2 includes a criterion for accessible authentication: people shouldn't have to solve puzzles or memorise and transcribe information without help like paste or autofill. Passkeys meet it naturally.
Policies for teams and admins
For business products, MFA is also an administration feature:
- let organisation admins require MFA for all members, or for certain roles
- show admins who has enrolled and which factors they use
- require phishing-resistant factors (passkeys or security keys) for admin accounts
- log every sign-in, factor change and recovery event for audits
Measure what matters
"MFA is available" is not a security outcome. Track:
- Enrolment rate: what share of active users have a second factor.
- Factor mix: how many use passkeys versus SMS. Aim to shift the mix towards stronger factors.
- Challenge completion rate: how often people complete an MFA prompt. Drops point to friction or bugs.
- Lockouts and recovery requests: spikes mean recovery needs work.
- Support tickets: the cost of friction in hours.
Common mistakes
- Forcing enrolment before users see any value.
- Making SMS the default because it's familiar.
- Six separate code boxes that break autofill and paste.
- Recovery that relies on the same phone that was lost.
- Unlimited push prompts with no number matching.
- No notification when security settings change.
How Flutter MFA will help
We're building Flutter MFA to bundle passkeys, biometrics, TOTP, OTP and backup codes behind one API, so teams can offer the right factor in the right moment without stitching five packages together, and with the recovery and step-up patterns above built in.

If you're adding authentication to a product or reviewing an existing login flow, we can help with design, implementation and a security review. See our custom software and IT consulting and security services, or get in touch.
Frequently asked questions
What is the most user-friendly second factor?
Passkeys and device biometrics. They're phishing-resistant and take a single tap. Authenticator apps (TOTP) are a strong fallback.
Are SMS codes still safe?
SMS is better than nothing but vulnerable to SIM swapping. Use it as a fallback, not the default, for sensitive accounts.
Should MFA be mandatory?
For admin accounts, financial actions and anything handling sensitive data, yes. For consumer apps, strongly encourage it at the right moment, make passkeys the easy default, and require it for high-risk actions.
How do we stop users getting locked out?
Require at least two recovery options at enrolment, such as backup codes and a second device, offer a clear self-service recovery path, and make sure support staff have a secure, documented process for verifying identity.

Written by
Co-Founder & CTO
Excels in developing innovative hardware and software solutions. With expertise in IoT, embedded systems, and data analytics, committed to tackling real-world challenges through advanced technology.




