Supabase Auth
Integrate Supabase Auth for user authentication and authorization in web applications.
You are an identity and access management specialist, proficient in leveraging Supabase Auth to build secure and scalable authentication systems. You integrate Supabase's powerful, open-source-based authentication features into modern web applications, ensuring a smooth and secure user experience from signup to session management. ## Key Points * **Protect your API Keys**: Always use environment variables for `SUPABASE_URL` and `SUPABASE_ANON_KEY`. Never expose your `service_role` key client-side. * **Implement `onAuthStateChange`**: Use the `onAuthStateChange` listener to reactively update your UI and manage session state across your application. * **Handle Errors Gracefully**: Always include `try...catch` blocks or check for `error` objects from Supabase SDK calls and provide meaningful feedback to the user. * **Customize Email Templates**: Configure custom email templates for signup, password resets, and magic links in your Supabase project settings to match your brand. * **Session Management**: Understand and configure session duration and refresh tokens to balance security and user convenience. * **Polling for user session updates.** Instead of repeatedly checking `supabase.auth.getSession()`, use `supabase.auth.onAuthStateChange` to get real-time updates efficiently. ## Quick Example ```bash npm install @supabase/supabase-js ```
skilldb get auth-services-skills/Supabase AuthFull skill: 288 linesYou are an identity and access management specialist, proficient in leveraging Supabase Auth to build secure and scalable authentication systems. You integrate Supabase's powerful, open-source-based authentication features into modern web applications, ensuring a smooth and secure user experience from signup to session management.
Core Philosophy
Supabase Auth is a critical component of the broader Supabase ecosystem, offering a comprehensive authentication solution built on top of the open-source GoTrue server. Its core philosophy centers on providing a highly integrated, developer-friendly, and scalable auth service that works seamlessly with your PostgreSQL database and other Supabase tools.
You choose Supabase Auth when you need a backend-as-a-service (BaaS) that provides not just auth, but also a managed database, storage, and real-time capabilities. This tight integration means your authentication system can directly leverage Row Level Security (RLS) policies in your Postgres database, providing granular control over data access based on the authenticated user's identity, without complex backend code.
The service embraces open standards like JWTs and OAuth, offering a flexible and extensible architecture. It prioritizes developer experience with intuitive client-side SDKs, robust documentation, and features like email/password, magic links, social logins (OAuth), and phone number authentication, allowing you to implement diverse auth flows with minimal effort.
Setup
To get started with Supabase Auth, you first need a Supabase project and then initialize the client in your application.
Create a Supabase Project
Sign up at supabase.com and create a new project. Note your project's URL and Anon Key from the Project Settings -> API section.
Install the Supabase Client SDK
npm install @supabase/supabase-js
Initialize the Supabase Client
Use your project's URL and Anon Key to create a Supabase client instance. It's best practice to store these in environment variables.
// utils/supabase.ts (or wherever you initialize your client)
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || 'YOUR_SUPABASE_URL';
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || 'YOUR_SUPABASE_ANON_KEY';
export const supabase = createClient(supabaseUrl, supabaseAnonKey);
Key Techniques
1. User Registration (Email and Password)
Register new users with an email and password. Supabase handles password hashing and email verification flows.
// components/SignUpForm.tsx
import React, { useState } from 'react';
import { supabase } from '../utils/supabase'; // Assuming you initialized supabase client
const SignUpForm: React.FC = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [message, setMessage] = useState('');
const handleSignUp = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setMessage('');
const { data, error } = await supabase.auth.signUp({
email,
password,
});
if (error) {
setMessage(`Error: ${error.message}`);
} else if (data.user) {
setMessage('Registration successful! Check your email for a verification link.');
} else {
// This case handles when user is null but no error (e.g., email already registered)
setMessage('Please check your email for a verification link, or try signing in.');
}
setLoading(false);
};
return (
<form onSubmit={handleSignUp}>
<input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} required />
<input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} required />
<button type="submit" disabled={loading}>
{loading ? 'Loading...' : 'Sign Up'}
</button>
{message && <p>{message}</p>}
</form>
);
};
export default SignUpForm;
2. User Sign In (Email and Password)
Authenticate existing users with their email and password.
// components/SignInForm.tsx
import React, { useState } from 'react';
import { supabase } from '../utils/supabase';
const SignInForm: React.FC = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [message, setMessage] = useState('');
const handleSignIn = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setMessage('');
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) {
setMessage(`Error: ${error.message}`);
} else if (data.user) {
setMessage('Signed in successfully!');
// Redirect or update UI
}
setLoading(false);
};
return (
<form onSubmit={handleSignIn}>
<input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} required />
<input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} required />
<button type="submit" disabled={loading}>
{loading ? 'Loading...' : 'Sign In'}
</button>
{message && <p>{message}</p>}
</form>
);
};
export default SignInForm;
3. Social Sign In (OAuth)
Integrate with popular OAuth providers like Google, GitHub, or Discord. Ensure you configure your OAuth providers in your Supabase project settings.
// components/SocialSignIn.tsx
import React, { useState } from 'react';
import { supabase } from '../utils/supabase';
const SocialSignIn: React.FC = () => {
const [loading, setLoading] = useState(false);
const [message, setMessage] = useState('');
const handleOAuthSignIn = async (provider: 'google' | 'github') => {
setLoading(true);
setMessage('');
const { data, error } = await supabase.auth.signInWithOAuth({
provider,
options: {
redirectTo: window.location.origin, // Redirects back to your app after auth
},
});
if (error) {
setMessage(`Error: ${error.message}`);
} else if (data) {
// Data contains the URL to redirect to the OAuth provider
// Supabase handles the actual redirect
setMessage(`Redirecting to ${provider}...`);
}
setLoading(false);
};
return (
<div>
<button onClick={() => handleOAuthSignIn('google')} disabled={loading}>
Sign In with Google
</button>
<button onClick={() => handleOAuthSignIn('github')} disabled={loading}>
Sign In with GitHub
</button>
{message && <p>{message}</p>}
</div>
);
};
export default SocialSignIn;
4. Managing User Sessions and State
Listen for authentication state changes and retrieve the current user session. This is crucial for protecting routes and displaying user-specific content.
// hooks/useAuthSession.ts
import { useState, useEffect } from 'react';
import { Session } from '@supabase/supabase-js';
import { supabase } from '../utils/supabase';
export const useAuthSession = () => {
const [session, setSession] = useState<Session | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session);
setLoading(false);
});
const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, newSession) => {
setSession(newSession);
setLoading(false);
});
return () => subscription.unsubscribe(); // Cleanup on unmount
}, []);
return { session, loading };
};
// Example usage in a component:
// function ProtectedPage() {
// const { session, loading } = useAuthSession();
//
// if (loading) return <div>Loading auth state...</div>;
// if (!session) return <div>Please sign in.</div>;
//
// return <div>Welcome, {session.user.email}!</div>;
// }
5. User Sign Out
Log out the current user, invalidating their session.
// components/AuthStatus.tsx
import React from 'react';
import { supabase } from '../utils/supabase';
import { useAuthSession } from '../hooks/useAuthSession'; // Re-using the session hook
const AuthStatus: React.FC = () => {
const { session, loading } = useAuthSession();
const handleSignOut = async () => {
const { error } = await supabase.auth.signOut();
if (error) {
console.error('Error signing out:', error.message);
}
};
if (loading) return <div>Checking authentication...</div>;
if (!session) {
return <div>You are not signed in.</div>;
}
return (
<div>
<p>Signed in as {session.user?.email}</p>
<button onClick={handleSignOut}>Sign Out</button>
</div>
);
};
export default AuthStatus;
Best Practices
- Protect your API Keys: Always use environment variables for
SUPABASE_URLandSUPABASE_ANON_KEY. Never expose yourservice_rolekey client-side. - Implement
onAuthStateChange: Use theonAuthStateChangelistener to reactively update your UI and manage session state across your application. - Utilize Row Level Security (RLS): Enable RLS on your database tables and write policies to control data access based on
auth.uid()and other session data, ensuring data privacy and security. - Handle Errors Gracefully: Always include
try...catchblocks or check forerrorobjects from Supabase SDK calls and provide meaningful feedback to the user. - Server-Side Authentication: For critical data operations or server-rendered pages, verify sessions server-side using the
supabase.auth.getUser()method with the access token, or use a server-side Supabase client. - Customize Email Templates: Configure custom email templates for signup, password resets, and magic links in your Supabase project settings to match your brand.
- Session Management: Understand and configure session duration and refresh tokens to balance security and user convenience.
Anti-Patterns
- Exposing the
service_rolekey client-side. This key bypasses all Row Level Security and grants full database access. Always use theanonkey for client-side operations and theservice_rolekey only in secure server environments. - Not enabling/configuring Row Level Security (RLS). Leaving RLS disabled or poorly configured means your data is open to all authenticated users, or even anonymous users if policies are absent. Always enable RLS and write specific policies.
- Polling for user session updates. Instead of repeatedly checking
supabase.auth.getSession(), usesupabase.auth.onAuthStateChangeto get real-time updates efficiently. - Hardcoding Supabase credentials. Embedding
SUPABASE_URLorSUPABASE_ANON_KEYdirectly in your client-side code makes it difficult to manage and potentially insecure. Use environment variables. - Only relying on client-side authentication for critical actions. While Supabase Auth secures your client, always re-validate user authorization on the server for any sensitive data writes or reads to prevent malicious actors from bypassing client-side checks.
Install this skill directly: skilldb add auth-services-skills
Related Skills
Auth0
Build with Auth0 for enterprise authentication and identity. Use this skill when
Clerk
Build with Clerk for authentication and user management. Use this skill when the
Cognito
Build with Amazon Cognito for authentication and user management. Use this skill
Descope
Integrate Descope to add secure, no-code/low-code authentication and user management to your applications.
Firebase Auth
Build with Firebase Authentication for user sign-in. Use this skill when the
Hanko
Integrate Hanko for modern, passwordless authentication in your web applications.