Skip to content

Supabase Authentication — Complete User Auth Setup for Your App

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about Supabase Authentication. We cover key concepts, practical examples, and best practices to help you master this topic.

Supabase Authentication provides a complete auth system with email/password, OAuth providers (Google, GitHub, Discord), magic links, phone auth, MFA, and session management built on PostgreSQL.

What You'll Learn

By the end of this lesson you will implement email/password signup and login, configure OAuth providers, enable magic links, manage sessions programmatically, and protect routes with auth guards.

Why It Matters

Building authentication from scratch is error-prone and time-consuming -- password hashing, token management, session storage, and Rate Limiting all require battle-tested implementations.

Real-World Use

DodaZIP uses Supabase Auth for user registration and login. When a user signs up via email or Google OAuth, a database trigger creates their profile row automatically, and sessions are managed entirely by Supabase.

flowchart LR
    U[User] -->|Sign Up| A[Supabase Auth]
    U -->|OAuth| P[Google/GitHub]
    P --> A
    A -->|JWT| C[Client App]
    C -->|Session Token| API[Supabase API]
    API -->|auth.uid()| DB[(PostgreSQL)]
    style A fill:#3ecf8e,color:#fff

Email and Password Authentication

The most common auth method for web applications.

# email_auth.py
# Email/password signup and login

import os
from supabase import create_client, Client

url = os.getenv("SUPABASE_URL", "https://example.supabase.co")
key = os.getenv("SUPABASE_ANON_KEY", "your-anon-key")
supabase: Client = create_client(url, key)

def sign_up(email: str, password: str):
    response = supabase.auth.sign_up({
        "email": email,
        "password": password,
    })
    print(f"Sign up response: {response}")
    if response.user:
        print(f"User created: {response.user.id}")
        print(f"Confirmation email sent to: {email}")
    return response

def sign_in(email: str, password: str):
    response = supabase.auth.sign_in_with_password({
        "email": email,
        "password": password,
    })
    print(f"Sign in response: {response}")
    if response.session:
        print(f"Session created: {response.session.access_token[:20]}...")
        print(f"User: {response.user.email}")
    return response

def sign_out():
    response = supabase.auth.sign_out()
    print("Signed out successfully")
    return response

sign_up("user@example.com", "secure-password-123")
sign_in("user@example.com", "secure-password-123")

OAuth Providers

Allow users to sign in with Google, GitHub, Discord, and more.

# oauth_auth.py
# OAuth authentication with Supabase

def configure_oauth():
    providers = {
        "Google": "Configure in Supabase Dashboard > Authentication > Providers",
        "GitHub": "Register OAuth app in GitHub Developer Settings",
        "Discord": "Create app in Discord Developer Portal",
        "Facebook": "Configure in Facebook Developers",
        "Apple": "Requires Apple Developer account",
        "Twitter": "Configure in Twitter Developer Portal",
    }
    
    print("OAuth Provider Configuration:")
    print()
    print("Dashboard setup:")
    print("  1. Go to Authentication > Providers in Supabase Dashboard")
    print("  2. Enable the provider you want")
    print("  3. Enter Client ID and Client Secret from the provider")
    print("  4. Set the redirect URL (shown in Supabase Dashboard)")
    print()
    print("Client-side sign-in:")
    print("  supabase.auth.signInWithOAuth({ provider: 'google' })")

def sign_in_with_google():
    print("Initiating Google OAuth...")
    print("  Redirecting to Google consent screen...")
    print("  User authorized...")
    print("  Redirecting back to application...")
    print("  Session established with JWT token")
    print("  User: user@gmail.com (from Google profile)")

configure_oauth()
sign_in_with_google()

Passwordless email login via magic links.

# magic_link.py
# Magic link authentication

def send_magic_link(email: str):
    supabase = create_client(
        os.getenv("SUPABASE_URL", "https://example.supabase.co"),
        os.getenv("SUPABASE_ANON_KEY", "your-anon-key")
    )
    
    response = supabase.auth.sign_in_with_otp({
        "email": email,
    })
    
    print(f"Magic link sent to: {email}")
    print(f"Response: {response}")
    print("User clicks link in email to sign in automatically")

send_magic_link("user@example.com")

Session Management

Handle tokens, refresh, and session lifecycle.

# session.py
# Session management with Supabase

import os
from supabase import create_client

supabase = create_client(
    os.getenv("SUPABASE_URL", "https://example.supabase.co"),
    os.getenv("SUPABASE_ANON_KEY", "your-anon-key")
)

def get_session():
    session = supabase.auth.get_session()
    if session:
        print(f"Active session found")
        print(f"Access token: {session.access_token[:30]}...")
        print(f"Expires at: {session.expires_at}")
        return session
    else:
        print("No active session")
        return None

def get_user():
    user = supabase.auth.get_user()
    if user:
        print(f"Current user: {user.user.email}")
        print(f"User ID: {user.user.id}")
        return user
    else:
        print("No user logged in")
        return None

def refresh_session():
    session = supabase.auth.refresh_session()
    print(f"Session refreshed")
    print(f"New token: {session.access_token[:30]}...")

get_session()
get_user()

Common Mistakes

  1. Not handling email confirmation: By default, Supabase requires email confirmation. Disable this only in development. Handle the confirmation flow properly in production.

  2. Storing JWTs in localStorage without protection: JWTs in localStorage are vulnerable to XSS. Use httpOnly cookies for production applications.

  3. Not checking session expiry on page load: Always call supabase.auth.getSession() when the app loads to restore or refresh the session.

  4. Mixing anon and service_role keys: The anon key respects RLS. The service_role key bypasses it. Use service_role only in secure server environments.

  5. Skipping rate limiting: Supabase applies rate limits on sign-in attempts. Implement exponential backoff in your client code.

Practice Questions

  1. What methods does Supabase Auth support for user sign-in? Email/password, OAuth providers, magic links, phone OTP, and multi-factor authentication.

  2. How do you get the current user in Supabase? Call supabase.auth.getUser() which returns the authenticated user object.

  3. What is a magic link? A one-time sign-in link sent via email that logs the user in when clicked, without requiring a password.

  4. How does Supabase handle session refresh? The SDK automatically refreshes sessions using a refresh token. Manual refresh is available via supabase.auth.refreshSession().

  5. Challenge: Implement a complete auth flow with sign up, email verification handling, sign in, session persistence across page reloads, and sign out, with appropriate error messages.

FAQ

Does Supabase support multi-factor authentication?

Yes. Supabase supports TOTP-based MFA. Enable it in the Authentication settings.

Can I use Supabase Auth with my own backend?

Yes. Verify JWTs in your own backend using Supabase's JWT secret to authorize requests.

How do I disable email confirmation?

Go to Authentication > Settings in the dashboard and toggle off 'Confirm email'.

Does Supabase support SAML or enterprise SSO?

Yes. SAML and SSO are available on the Team and Enterprise plans.

What happens when a user's session expires?

The SDK tries to refresh the session. If the refresh token is also expired, the user must sign in again.

Mini Project

Create a complete authentication module with signup, login, OAuth provider integration, session management, and route protection.

def auth_module():
    features = [
        "User registration with email/password",
        "User login with email/password",
        "Google OAuth provider integration",
        "GitHub OAuth provider integration",
        "Magic link passwordless login",
        "Session persistence on page reload",
        "Automatic token refresh",
        "Sign out with session cleanup",
        "Protected route guard",
        "User profile data access",
    ]
    
    print("Auth Module Features:")
    for feature in features:
        print(f"  [ ] {feature}")

auth_module()

What's Next

Next: Realtime Subscriptions for live data updates.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro