Authentication with Next.js and Supabase: Step by Step
29 April 2026 · by Yunmin Shin
Why Use Supabase for Authentication?
Authentication is one of the most error-prone parts of any web application. Rolling your own auth means managing password hashing, session tokens, email verification, and OAuth flows — each with potential security vulnerabilities.
Supabase Auth handles all of this and integrates directly with its PostgreSQL database. User identities are available in your Row-Level Security policies, so you can control data access at the database level without writing permission checks in your application code.
How Do You Set Up Supabase Auth in Next.js?
Install the required packages:
npm install @supabase/supabase-js @supabase/ssr
Create two client utilities:
Server client (utils/supabase/server.ts) — uses cookies() from Next.js to read the session server-side. Required for server components, middleware, and route handlers.
Browser client (utils/supabase/client.ts) — a singleton that persists the session in browser local storage. Used in client components.
Add your Supabase URL and anon key to .env.local. The anon key is designed to be public — security comes from RLS policies, not key secrecy.
How Do You Implement Email and Password Auth?
Supabase provides signUp, signInWithPassword, and signOut methods. Use these inside Server Actions:
"use server";
import { createClient } from "@/utils/supabase/server";
import { redirect } from "next/navigation";
export async function login(formData: FormData) {
const supabase = await createClient();
const { error } = await supabase.auth.signInWithPassword({
email: formData.get("email") as string,
password: formData.get("password") as string,
});
if (error) redirect("/login?error=invalid_credentials");
redirect("/dashboard");
}
Supabase handles email confirmation out of the box. Users receive a confirmation email and click a link before their account is active.
How Do You Add Google OAuth?
Enable the Google provider in the Supabase dashboard and configure your OAuth credentials from the Google Cloud Console. Then trigger the OAuth flow from your client:
await supabase.auth.signInWithOAuth({
provider: "google",
options: { redirectTo: `${origin}/auth/callback` },
});
Create a /auth/callback Route Handler that exchanges the code for a session using supabase.auth.exchangeCodeForSession(code). Supabase's Next.js quickstart provides the exact implementation.
How Do You Protect Routes?
Use Next.js Middleware to check for a valid session before serving protected pages:
// middleware.ts
const { data: { user } } = await supabase.auth.getUser();
if (!user) return NextResponse.redirect(new URL("/login", request.url));
This check runs on the Edge before the page renders — unauthenticated users never see a flash of protected content.
Always use getUser() rather than getSession() in server-side code. getUser() validates the session with Supabase's servers on every call, preventing session token forgery. getSession() only reads from the cookie without validation.
Ready to Build Something Fast?
Get a free quote on LINE. We reply within 24 hours.
Ready to build something fast and scalable?
Get a free project quote on LINE. We reply within 24 hours.
무료 견적 on LINE