Skip to content
Chapter 53Lesson 10

Quiz - Authentication flows

Quiz progress

0 / 0

You’re configuring emailAndPassword and want users verified before they ever hold a session. A teammate suggests requireEmailVerification: true together with autoSignIn: true so people “land in the app faster.” Why is that a broken state?

The two contradict each other: verification says “don’t trust them until they confirm the inbox,” while autoSignIn issues a session immediately — so the right pairing is autoSignIn: false.
autoSignIn only works with OAuth providers, so it’s silently ignored on an email-and-password sign-up.
It’s fine — requireEmailVerification overrides autoSignIn, so the user still won’t get a session until they verify.

A sign-in endpoint needs to survive an attacker who rotates IP addresses to guess one known account’s password. Which statement about Better Auth’s out-of-the-box defenses is correct?

Core Better Auth ships only a per-IP rate limit — there is no built-in per-account lockout counter, so the per-email limit is a second key you add yourself.
Better Auth ships both a per-IP limit and a per-account failed-attempt lockout, so an IP-rotating attacker is already stopped by default.
Better Auth ships a per-account lockout but no per-IP limit, so credential stuffing from a single IP slips through until you add rate limiting.

A user clicks the verification link and emailVerified flips to true. What does that flag actually grant?

It proves the user controls that inbox — a capability floor. Every per-action authorization check (org membership, role, ownership) still runs on top of it.
It authorizes the user for everything a normal member can do, so per-action checks can be skipped for verified users.
It marks the account as fully trusted, which is why the verify endpoint can safely return distinct copy for “expired” versus “never existed.”

You wire the password-reset happy path: the link arrives, the new password saves, the user lands signed in, every test passes. Yet a security reviewer calls it a back door. What’s the most likely cause?

revokeSessionsOnPasswordReset was left at its default false, so an attacker holding a pre-reset session keeps their access after the reset.
The reset token lived in the URL, which is never acceptable and always an account-takeover hole.
The reset link used a 10-minute expiry instead of matching the verification link’s one hour.

You’re enabling the magicLink() plugin. Which configuration line is the single most important one to get right, and why?

storeToken: 'hashed' — the plugin defaults to 'plain', so without it a leaked verification row is a live, working sign-in link.
disableSignUp: true — leaving it false lets anyone create an account, which is the main risk of magic links.
expiresIn: 60 * 60 — matching the verification link’s one-hour fuse keeps the UX consistent across the chapter.

During enrollment a user calls authClient.twoFactor.enable({ password }), scans the QR, and the screen shows their recovery codes. Is two-factor now active on the account?

No — enable() only generates and shows the secret. 2FA arms only after verifyTotp confirms the user typed a working code, which is what flips twoFactorEnabled to true.
Yes — enable() succeeding is the commit; verifyTotp afterward is just an optional sanity check.
Yes, but only if trustDevice was passed; otherwise the account stays unprotected.

Your app runs at app.example.com, but you set rpID: 'example.com' in the passkey() config. What symptom should you expect?

Registration succeeds, but every sign-in (assertion) silently fails, because the passkey was scoped to a domain the request never comes from.
Registration fails immediately with an origin error, so you catch the mistake before any passkey is stored.
Everything works at app.example.com, but the passkey also wrongly works at marketing.example.com, widening the attack surface.

You register http://localhost:3000/api/auth/callback/google in the Google console, but staging keeps failing the OAuth round-trip. Which of these would silently break it?

A trailing slash or scheme difference — …/callback/google/ or an https vs http mismatch — because redirect URIs are matched exactly, with no wildcards.
Reusing the same client_id across dev and staging, which Google rejects at the redirect step.
Omitting redirectURI from the socialProviders block, which means Better Auth never tells Google where to return.

A teammate wants to add a provider to trustedProviders “because lots of our users have it.” Why is that reasoning unsafe?

A trusted provider auto-links onto a matching-email account with no email_verified backstop, so the list itself IS the trust — popularity says nothing about whether its email claim is one you’d stake an account on.
It’s safe — Better Auth still requires the provider to assert email_verified: true before any trusted auto-link, so a weak provider can’t actually link.
The real risk is the empty trustedProviders list, which trusts every provider by default until you populate it.

Quiz complete

Score by topic