Back to blog

Why 6-Digit Email OTP Outperforms Magic Links in Next.js & Supabase

Learn why Magic Links fail in production and how to implement a secure, seamless 6-digit email OTP authentication flow in Next.js with Supabase.

Oct 16, 2026
7
directions
notes from delivery practice
3
levels
strategy · process · tools
1
library
guides · checklists · cases
See cases

Why Magic Links Fail in Real-World Environments

Passwordless authentication via magic links has long been praised for its simplicity. However, in production, magic links frequently break where developers least expect it. Common failure modes include social media in-app browsers, aggressive anti-phishing bots that pre-fetch and invalidate links before the user clicks, and deep-link routing mismatches between mobile and desktop browsers.

Switching to a 6-digit numeric OTP (One-Time Password) eliminates these vulnerabilities. The user remains on the exact page where they initiated the login flow, checks their email inbox for the numeric code, and enters it without navigating away. Here is how to implement this architecture cleanly using Next.js (App Router) and Supabase.

Step 1: Updating the Supabase Email Template

By default, Supabase sends confirmation links. To switch to numeric codes, navigate to Authentication → Email Templates → Magic Link in the Supabase dashboard and replace the link markup with the {{ .Token }} variable.

Ensure that {{ .ConfirmationURL }} is entirely removed from the template. Leaving it in place causes confusion by providing two different authentication paths. In addition, configure a dedicated SMTP service (such as Resend, Postmark, or AWS SES), as the default Supabase mailer is strictly intended for local testing and rate-limits quickly.

Step 2: Server-Side Client and Cookie Management

In modern Next.js applications, authentication tokens must be managed securely on the server. Utilizing @supabase/ssr allows you to create a centralized Supabase server client that synchronizes cookie storage between Server Components, Server Actions, and Route Handlers without exposing private keys to the client.

Step 3: Dispatching the Code Securely

When creating the API route to dispatch the one-time code, address two critical security aspects:

  • IP-based Rate Limiting: Protect your endpoint from spam attacks and unneeded SMTP consumption by throttling requests per client IP.
  • Preventing Account Enumeration: Always return a generic success response regardless of whether the email is present in your database, preventing attackers from harvesting valid accounts.

Calling supabase.auth.signInWithOtp with the argument shouldCreateUser: true generates the token and initiates delivery while creating the user account if it does not yet exist.

Step 4: Verification and Brute-Force Prevention

A 6-digit passcode offers only one million possible combinations. Without strict rate limiting, an automated brute-force attack can guess the active token before it expires. The verification endpoint calling supabase.auth.verifyOtp must apply rate limiting keyed to the email address rather than the IP address, since distributed attackers easily cycle proxy IPs.

A sensible threshold is capping verification at 5 failed attempts per 10 minutes per email. Upon successful validation, the server client persists the user session directly into secure HTTP-only cookies.

Step 5: Session Refreshing via Next.js Middleware

To keep user sessions active and authenticated across requests, implement session validation within middleware.ts. Crucially, rely on supabase.auth.getUser() rather than merely reading the session object from cookies. The getUser() method verifies the authentication state with the Supabase auth server, guaranteeing that revoked or altered credentials cannot access protected routes.

Strategic Takeaway for Web Applications

Transitioning from magic links to numeric OTP authentication drastically improves conversion rates, minimizes user frustration, and removes deep-link dependencies. At ViAcore, our engineering team builds secure, scalable authentication flows that safeguard business data while delivering a friction-free user journey.

Services on this topic

Need this for your project?

Development turnkey: analysis → implementation → launch → support. Tell us about your task — we will reply with an estimate.

About the direction

Relevant articles