| name | supabase-auth |
| description | Supabase Auth + RLS + Middleware setup.
Client/server helpers, middleware, RLS policies,
and role-based access (user/teacher/admin).
Use when adding authentication to a Next.js + Supabase project.
|
| allowed-tools | ["Read","Write","Edit","Bash","Grep","Glob","Agent"] |
Supabase Auth — Authentication Setup
Add authentication to a Next.js + Supabase project.
Interview
- Roles: user only / user + teacher / user + teacher + admin
- Registration method: Email+password / Magic Link / OAuth (Google, etc.)
- Teacher code: Require a code for teacher registration?
- Email confirmation: Required / Not required (recommend OFF during development)
What Gets Built
1. Supabase Client Helpers
src/lib/supabase/
├── client.ts # Browser client (createBrowserClient)
├── server.ts # Server Component / Route Handler
└── middleware.ts # Middleware client
2. Middleware
src/middleware.ts
- Refresh auth sessions
- Redirect unauthenticated users (to
/login)
- Define public routes (
/, /login, /signup, /api/webhook, etc.)
3. Auth Pages
src/app/(auth)/
├── login/page.tsx # Login (email + password)
├── signup/page.tsx # Registration (with role selection)
└── callback/route.ts # OAuth / Magic Link callback
4. Profile Table + RLS
create table profiles (
id uuid primary key references auth.users(id) on delete cascade,
role text default 'user' check (role in ('user', 'teacher', 'admin')),
display_name text,
created_at timestamptz default now()
);
alter table profiles enable row level security;
create policy "Users can view own profile"
on profiles for select using (auth.uid() = id);
create policy "Users can update own profile"
on profiles for update using (auth.uid() = id);
create or replace function public.handle_new_user()
returns trigger as $$
begin
insert into public.profiles (id, role, display_name)
values (new.id, 'user', new.raw_user_meta_data->>'display_name');
return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
after insert auth.users
public.handle_new_user();
5. Supabase Dashboard Settings
- Site URL: Your production URL
- Redirect URLs:
http://localhost:3000/**, https://{domain}/**
- Email confirmation: Recommend OFF during development
- Email templates: Customize as needed
Role-Based Access Pattern
const supabase = await createClient()
const { data: { user } } = await supabase.auth.getUser()
const { data: profile } = await supabase
.from('profiles')
.select('role')
.eq('id', user.id)
.single()
if (profile.role !== 'teacher') redirect('/dashboard')