Authentication
Supabase Auth integration with server-side session management.
Overview
Authentication is handled by Supabase Auth with server-side session management through the Next.js proxy.
Supported Methods
- Email/Password with verification
- Magic links (OTP)
- OAuth (Google, GitHub, Apple, and other Supabase-supported providers)
Architecture
How It Works
The user submits a form to the existing same-origin /api/auth/* URL. The
Next.js catch-all passes the request to Hono, the auth handler calls the auth
service, and the service uses the cookie-backed Supabase server client. The
existing Next.js proxy continues refreshing browser sessions through the
Supabase session helper.
Password forms keep provider and validation failures on the current form. After
a successful sign-in, sign-up, password setup, or sign-out, the shared auth
transition helper clears cached session and user-status results before the next
route renders.
Auth Service
The server-only auth service (src/services/auth/service.ts) owns Supabase Auth
calls and their redirect results. Password routes preserve the supplied password;
only email addresses are trimmed at the Hono boundary.
| Password result | Destination |
|---|---|
| Sign-up creates a session immediately | /pricing with success status |
| Sign-up requires email confirmation | / with confirmation status |
| Password sign-in succeeds | /dashboard with success status |
| Provider or validation fails | Current auth form with error detail |
The API reference lists the exact response shapes. Keep the service's validation, existing-account, and provider-error branches when customizing it.
API Routes
The Hono auth module trims the email, preserves the password, calls the auth service, and returns its JSON result with a success or failure status.
Client-side password transitions
Use the shipped mutation hooks rather than calling Supabase from browser components. After a successful password transition, clear session-dependent query results before navigating:
const queryClient = useQueryClient();
const signUpMutation = useSignUpMutation();
const result = await signUpMutation.mutateAsync({ email, password });
if (result.ok) {
reconcileAuthTransition(queryClient);
router.push(result.redirectPath);
}Session Management
Proxy session refresh
The Next.js entrypoint is src/proxy.ts. It calls the session helper in
src/lib/supabase/middleware.ts for matched requests and preserves refreshed
cookies when the existing Markdown negotiation path rewrites a response.
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 session = useSession();
const user = session?.user ?? null;Protected Routes
Protect the dashboard route tree in its server layout. getUser() validates the
request cookies with Supabase before any dashboard shell or nested route can
render:
import { redirect } from "next/navigation";
import { createSupabaseServerClient } from "@/lib/supabase/server";
export default async function DashboardLayout({ children }) {
const supabase = await createSupabaseServerClient();
const {
data: { user },
error,
} = await supabase.auth.getUser();
if (error || !user) {
redirect("/signin");
}
return children;
}Keep client status queries for account and billing data, not for route admission. An unauthenticated request redirects before protected HTML is sent.
OAuth Setup
Enable Provider in Supabase
Go to Supabase Dashboard → Authentication → Providers
Configure OAuth App
Create an OAuth app in the Google, GitHub, or Apple developer 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?