Skip to main content
Supabase Authentication provides a complete user management system that handles authentication, authorization, and user data. Built on top of PostgreSQL Row Level Security (RLS), it gives you fine-grained control over data access.

Features

Supabase Auth offers multiple authentication methods:
  • Email & Password: Traditional authentication with optional email confirmation
  • Magic Links: Passwordless authentication via email
  • OAuth Providers: Social login with Google, GitHub, Apple, and more
  • Phone Authentication: SMS-based login
  • Multi-Factor Authentication (MFA): Add an extra layer of security with TOTP
  • Anonymous Sign-ins: Allow users to explore your app before registering

How It Works

Authentication in Supabase follows these core principles:
  1. User Identity: Users are stored in the auth.users table
  2. Sessions: JWT tokens are issued and automatically refreshed
  3. Row Level Security: Database policies control data access based on user identity
  4. Secure by Default: All auth endpoints use secure cookies and HTTPS
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  process.env.SUPABASE_URL,
  process.env.SUPABASE_ANON_KEY
)

// Check current session
const { data: { session } } = await supabase.auth.getSession()

// Listen for auth changes
supabase.auth.onAuthStateChange((event, session) => {
  console.log(event, session)
})

Authentication Flow

1

Initialize Client

Create a Supabase client with your project URL and anon key
2

Sign Up/Sign In

Users authenticate using their preferred method (email, OAuth, etc.)
3

Session Management

Supabase automatically manages JWT tokens and refreshes them
4

Access Control

Use Row Level Security policies to control data access

Client Setup

Server-Side (Next.js)

app/lib/supabase/server.ts
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'

export async function createClient() {
  const cookieStore = await cookies()

  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll()
        },
        setAll(cookiesToSet) {
          try {
            cookiesToSet.forEach(({ name, value, options }) => 
              cookieStore.set(name, value, options)
            )
          } catch {
            // The `setAll` method was called from a Server Component.
            // This can be ignored if you have proxy refreshing user sessions.
          }
        },
      },
    }
  )
}

Client-Side (Browser)

app/lib/supabase/client.ts
import { createBrowserClient } from '@supabase/ssr'

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!
  )
}

User Metadata

Store additional user information in two places:
  • User Metadata: Public data accessible in JWT tokens
  • App Metadata: Private data only accessible server-side
const { data, error } = await supabase.auth.signUp({
  email: '[email protected]',
  password: 'secure-password',
  options: {
    data: {
      first_name: 'John',
      age: 27,
    }
  }
})

Security Best Practices

Never expose your service_role key in client-side code. Use the anon key for client applications.

Enable Email Confirmation

Verify user email addresses before granting access to sensitive features

Implement RLS Policies

Always enable Row Level Security on tables containing user data

Use Secure Passwords

Enforce strong password requirements in your application

Enable MFA

Offer multi-factor authentication for enhanced security

Next Steps

Sign Up Users

Learn how to register new users

Sign In Methods

Implement various sign-in methods

OAuth Integration

Add social login providers

Multi-Factor Auth

Secure accounts with MFA

Build docs developers (and LLMs) love