Supabase Auth + 2FA Kit for Next.js (TOTP, RLS)

By (author)Mania Ashar

Tech stack:
JS
TS
CSS
Next.js
React
Supabase
PG
TW

Sign-up, sign-in and authenticator-app 2FA for Next.js + Supabase. Server-side 2FA check for API routes, Security page (2FA on/off), AuthGuard and an ...
read more
AI Contributions:10
Published At:October 21, 2026
Files Included:23 file(s)
Updated At:October 23, 2026

Read Me

Supabase Auth + 2FA Kit for Next.js (App Router)

Add sign-up, sign-in and authenticator-app 2FA (TOTP) to a Next.js app in about 10 minutes, with the parts people usually get wrong already handled: 2FA enforced on the server, half-finished enrolments cleaned up, a Security page to turn 2FA on or off, and an RLS template so every user only sees their own rows.

See it working: this code runs in production in TradeFlow AI, tradeflow-ai-phi.vercel.app (free sign-up). Source: github.com/amnaatgit/tradeflow-ai.

Extracted and cleaned up from TradeFlow AI, a hackathon app that uses this exact flow. The kit builds cleanly with Next.js 15 (next build, strict TypeScript, ESLint).

What you get

PieceFileWhat it does
Sign upapp/auth/sign-up/page.tsxEmail + password + confirm. Detects "already registered" (both Supabase modes) and handles email confirmation on/off.
Sign inapp/auth/sign-in/page.tsxSends 2FA users to the code screen, everyone else to the optional 2FA setup. Friendly errors.
2FA setupcomponents/mfa-setup.tsxQR code + manual key, verifies the first code, removes stale unverified factors. Optional or mandatory.
2FA verifycomponents/mfa-verify.tsxThe 6-digit step at sign-in; upgrades the session to aal2.
Security pagecomponents/security-settings.tsxShows 2FA status; turn on, or turn off with a confirm step.
Page guardcomponents/auth-guard.tsxRedirects signed-out users, forces the code for 2FA accounts, and shows Retry instead of an endless "Loading…".
API guardlib/supabase/server.tsrequireUser(token) validates the token and rejects aal1 tokens for accounts with 2FA on (403). Returns a Supabase client that runs as the user, so RLS applies.
Fetch helperlib/auth-fetch.tsCalls your API routes as the signed-in user.
RLS templatesupabase/rls-template.sqlPer-user table with the four policies, an index, and an optional "aal2 required" policy.

Everything else is plain Tailwind (components/ui.tsx), with no UI library needed.

Setup (10 minutes)

  1. npm i @supabase/ssr @supabase/supabase-js
  2. Copy lib/, components/ and app/ into your project. Change paths and the app name in lib/auth-config.ts.
  3. Add .env.local: NEXT_PUBLIC_SUPABASE_URL=... NEXT_PUBLIC_SUPABASE_ANON_KEY=...
  4. In Supabase: Authentication → Multi-Factor → enable TOTP (it is on by default in new projects).
  5. Optional: run supabase/rls-template.sql for your first per-user table.

Protect pages and API routes

// app/(app)/layout.tsx: every page inside needs a session (+ the 2FA code if enabled)
<AuthGuard need="aal2">{children}</AuthGuard>
// app/api/anything/route.ts
const body = await req.json().catch(() => ({}));
const auth = await requireUser(getAccessToken(req, body));
if (!auth.ok) return NextResponse.json({ error: auth.error }, { status: auth.status });
const { data } = await auth.supabase.from("notes").select("*"); // RLS: only this user's rows
// client side
const res = await authFetch("/api/anything", { some: "data" });

The flow

  1. Sign up → "Account created, sign in" (or "check your email" if confirmation is on)
  2. Sign in → 2FA on? Enter code : Turn on 2FA (optional, can skip)
  3. App pages behind AuthGuard. Security page to turn 2FA on/off.
  4. API routes reject missing or invalid tokens (401) and missing 2FA (403).

Why it's safer than the usual examples

  • A client-side guard alone is not security, so the kit checks the token and the 2FA level on the server for every API call.
  • Abandoned QR enrolments make the next enroll() fail; the kit removes them first.
  • Data isolation is done with Row Level Security, not with where user_id = ... in your code.

Contributors

Amna Shahzad, Mania Ashar and Bisma Shahid. MIT licensed.

Loading

Loading

Loading

More like this View all

Smart Inventory & Auto-Merging Catalog API

Production-ready Next.js 14 inventory system with real-time catalog search, quantity auto-merging logic, and Supabase RLS security.

  • 0

    Ratings

  • 1

    Files

    • Next.js
    • TS
    • +5

    Tech stack

Supabase TOTP 2FA for Next.js App Router

Drop-in 2FA for Next.js and Supabase: authenticator setup with a QR code, a code check at sign-in, and a guard that blocks pages, API routes and database rows until 2FA is done.

  • 0

    Ratings

  • 5

    Files

    • JS
    • TS
    • +2

    Tech stack

AI-Receipt-Scanner

This is a clean, decoupled, and production-ready implementation of an AI-powered receipt scanner. It enables users to upload grocery receipts, parses them using Google Gemini 1.5 Flash, performs serve

  • 0

    Ratings

  • 11

    Files

    • TS
    • JS
    • +7

    Tech stack