Authentication
Supabase Auth integration with server-side session management.
Overview
Authentication is handled by Supabase Auth with server-side session management via Next.js middleware.
Supported Methods
- Email/Password with verification
- Magic links (OTP)
- OAuth (Google, GitHub, etc.)
Architecture
How It Works
1. User submits form → calls API route
2. API route → calls auth service
3. Auth service → calls Supabase Auth
4. Supabase returns session/tokens
5. Middleware refreshes session on each requestAuth Service
The auth service (src/services/auth/service.ts) contains all authentication logic. It uses the "server-only" pragma to prevent client-side imports:
import "server-only";
import { createSupabaseServerClient } from "@/lib/supabase/server";
export async function signUp({ email, password }: SignUpParams) {
const supabase = await createSupabaseServerClient();
const { error, data } = await supabase.auth.signUp({
email,
password,
options: {
emailRedirectTo: getURL("/auth/callback"),
},
});
if (error) {
return { ok: false, redirectPath: getErrorRedirect("/signup", error.message) };
}
return { ok: true, redirectPath: "/" };
}
export async function signInWithPassword({ email, password }: PasswordSignInParams) {
const supabase = await createSupabaseServerClient();
const { error, data } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) {
return { ok: false, redirectPath: getErrorRedirect("/signin", error.message) };
}
return { ok: true, redirectPath: "/" };
}
export async function signOut() {
const supabase = await createSupabaseServerClient();
await supabase.auth.signOut();
return { ok: true, redirectPath: "/signin" };
}API Routes
API routes call the auth service and return JSON:
import { NextResponse } from 'next/server';
import { signUp } from '@/services/auth';
export async function POST(request: Request) {
const body = await request.json();
const result = await signUp(body);
return NextResponse.json(result, {
status: result.ok ? 200 : 400,
});
}Client-Side Usage
Sign Up
const response = await fetch('/api/auth/sign-up', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
const result = await response.json();
if (result.ok) {
window.location.href = result.redirectPath;
}Using the Auth Hooks
The template includes React hooks for auth mutations:
export function useSignUp() {
return useMutation({
mutationFn: async ({ email, password }) => {
const res = await fetch('/api/auth/sign-up', {
method: 'POST',
body: JSON.stringify({ email, password }),
});
return res.json();
},
});
}In components:
const { mutate: signUp, isPending } = useSignUp();
signUp({ email, password }, {
onSuccess: (result) => {
if (result.ok) router.push(result.redirectPath);
},
});Session Management
Middleware
The middleware (src/middleware.ts) refreshes the session on each request:
import { updateSession } from '@/lib/supabase/middleware';
export async function middleware(request: NextRequest) {
return await updateSession(request);
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg)$).*)'],
};Getting the Current User
In server components or API routes:
import { createSupabaseServerClient } from '@/lib/supabase/server';
const supabase = await createSupabaseServerClient();
const { data: { user } } = await supabase.auth.getUser();In client components, use the session hook:
import { useSession } from '@/hooks/auth';
const { user, isLoading } = useSession();Protected Routes
Check for authentication in page components:
import { redirect } from 'next/navigation';
import { createSupabaseServerClient } from '@/lib/supabase/server';
export default async function DashboardPage() {
const supabase = await createSupabaseServerClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) {
redirect('/signin');
}
return <Dashboard user={user} />;
}OAuth Setup
Enable Provider in Supabase
Go to Supabase Dashboard → Authentication → Providers
Configure OAuth App
Create OAuth app in Google/GitHub console and get credentials
Add Credentials to Supabase
Enter Client ID and Secret in Supabase provider settings
Set Redirect URLs
Add https://<project-ref>.supabase.co/auth/v1/callback to the OAuth provider's
allowed redirects. This is the provider callback, not your app's hosted URL.
Configure the Hosted App URL
After your hosted domain is assigned, open Supabase URL Configuration. Set Site URL to https://<your-domain>, add https://<your-domain>/** to Redirect URLs, and save both fields before testing OAuth.
Database Trigger
New users are automatically added to the users table via a database trigger:
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS trigger AS $$
BEGIN
INSERT INTO public.users (id, email)
VALUES (new.id, new.email);
RETURN new;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE PROCEDURE public.handle_new_user();Related
- Payments - Connect auth to billing
- Environment Variables - Auth configuration
- API Routes - All auth endpoints
Was this page helpful?