Authentication
KwikSaaS uses Supabase Auth for secure, session-based authentication. This guide covers setup, configuration, and customization of all auth flows.Auth is pre-configured out of the box. This guide helps you understand and
customize the implementation.
What’s Included
- Email/password — Sign up with email verification, sign in, and password management
- OAuth providers — Pre-configured Google and GitHub sign-in
- Magic links — Passwordless authentication via email
- Password reset — Secure reset flow with email confirmation
- Protected routes — Middleware-based route protection
- Session management — Server and client-side session handling
Prerequisites
Before configuring auth, ensure you have:Supabase project
Create a project at supabase.com. You’ll need the project URL and anon key.
Configure Supabase URLs
Go to Supabase Dashboard → Authentication → URL Configuration:| Setting | Value |
|---|---|
| Site URL | http://localhost:3000 (dev) or https://yourdomain.com (prod) |
| Redirect URLs | http://localhost:3000/auth/callback |
OAuth Providers
Google OAuth
Create OAuth credentials
- Go to Google Cloud Console
- Create a new project or select existing
- Navigate to APIs & Services → Credentials
- Click Create Credentials → OAuth client ID
- Select Web application
- Add authorized redirect URI from Supabase (found in provider settings)
GitHub OAuth
Create OAuth App
- Go to GitHub Settings → Developer settings → OAuth Apps
- Click New OAuth App
- Set Homepage URL to your site
- Set Authorization callback URL from Supabase
Test OAuth by clicking the Google/GitHub buttons on
/sign-in. You should be
redirected to the provider and back to your dashboard.Auth Flows
Sign Up Flow
Magic Link Flow
- User enters email on
/sign-in - Server action calls
supabase.auth.signInWithOtp() - User receives email with magic link
- Click redirects to
/auth/callback - Session is created and user lands on dashboard
Password Reset Flow
- User clicks “Forgot password” →
/forgot-password - Enter email, server action sends reset email
- Email contains link to
/reset-password?code=... /auth/callbacksets recovery cookie and redirects- User enters new password on
/reset-password
File Structure
Protected Routes
Middleware insrc/lib/supabase/middleware.ts handles route protection:
- Unauthenticated users → Redirected away from
/dashboard/* - Authenticated users → Redirected away from
/sign-in,/sign-up,/forgot-password(unless in recovery mode)
Adding New Protected Routes
To protect additional routes, update the middleware patterns:Auth Context
Access user state anywhere in your app:AuthProvider wraps the app in layout.tsx and:
- Listens to Supabase auth state changes
- Identifies users in PostHog (if configured)
- Provides
signOuthelper
Server Actions
All auth operations use server actions insrc/app/(auth)/actions.ts:
| Action | Purpose |
|---|---|
signIn | Email/password sign in |
signUp | Create new account |
signInWithMagicLink | Send magic link email |
signInWithOAuth | Initiate OAuth flow |
sendPasswordResetEmail | Request password reset |
resetPassword | Set new password |
signOut | End session |
Email Templates
Auth emails are sent via Resend (if configured) or Supabase’s default SMTP.Configure Resend (Recommended)
Verify your domain
Add SPF, DKIM, and DMARC records in your DNS provider as shown in Resend
dashboard.
Email Template Files
Custom React Email templates are insrc/components/emails/:
MagicLinkEmail.tsxConfirmEmailTemplate.tsxResetPasswordEmail.tsx
Troubleshooting
OAuth redirect fails
OAuth redirect fails
Check Supabase URL Configuration:
- Site URL must match your app URL exactly
- Redirect URLs must include
/auth/callback - For local dev, use
http://localhost:3000, not127.0.0.1
- Client ID and Secret are correct
- Redirect URI in provider console matches Supabase
Email verification not arriving
Email verification not arriving
Check: 1. Spam/junk folder 2. Supabase rate limits (4 emails/hour on free
tier) 3. Email templates are enabled in Supabase dashboard 4. If using Resend,
verify domain is confirmed
Session not persisting
Session not persisting
Possible causes: - Cookies blocked by browser -
NEXT_PUBLIC_SITE_URL
doesn’t match actual URL - Middleware not running (check middleware.ts
matcher)Reset password shows error
Reset password shows error
Recovery flow requires:
- Valid reset link (not expired)
- Recovery cookie set by
/auth/callback - Correct
type=recoveryin callback URL