OAuth Provider Setup Guide¶
Complete guide for configuring Google and GitHub OAuth providers for local development and testing with Supabase Auth.
Table of Contents¶
- Prerequisites
- Google OAuth Setup
- GitHub OAuth Setup
- Environment Configuration
- Supabase Configuration
- Testing the Configuration
- Production Deployment
- Troubleshooting
Prerequisites¶
Before setting up OAuth providers, ensure you have:
- Docker Desktop installed and running
- Supabase CLI installed (
brew install supabase/tap/supabase) - Deno runtime installed
- A Google account (for Google OAuth)
- A GitHub account (for GitHub OAuth)
Google OAuth Setup¶
Step 1: Create a Google Cloud Project¶
- Go to Google Cloud Console
- Click the project dropdown at the top → New Project
- Enter project name:
Musingly Local Dev(or your preferred name) - Click Create
- Wait for project creation, then select it from the dropdown
Step 2: Enable Required APIs¶
- Go to APIs & Services → Library
- Search for "Google+ API" and click on it
- Click Enable
- (Optional) Also enable "Google People API" for profile data
Step 3: Configure OAuth Consent Screen¶
- Go to APIs & Services → OAuth consent screen
- Select External user type → Click Create
- Fill in the required fields:
| Field | Value |
|---|---|
| App name | Musingly |
| User support email | Your email |
| Developer contact email | Your email |
- Click Save and Continue
- Scopes: Click Add or Remove Scopes
- Select:
openid,email,profile - Click Update → Save and Continue
- Test users: Add your email address
- Click Save and Continue → Back to Dashboard
Step 4: Create OAuth Credentials¶
- Go to APIs & Services → Credentials
- Click + Create Credentials → OAuth client ID
- Select Web application
- Configure:
| Field | Value |
|---|---|
| Name | Musingly Local Dev |
| Authorized JavaScript origins | http://localhost:3000 |
http://localhost:54321 |
|
| Authorized redirect URIs | http://localhost:54321/auth/v1/callback |
- Click Create
- Copy and save the Client ID and Client Secret
Example credentials:
Client ID: 123456789012-abcdefghijklmnop.apps.googleusercontent.com
Client Secret: GOCSPX-AbCdEfGhIjKlMnOpQrStUvWxYz
GitHub OAuth Setup¶
Step 1: Create GitHub OAuth App¶
- Go to GitHub Settings → Developer Settings
- Click OAuth Apps in the sidebar
- Click New OAuth App
- Fill in the form:
| Field | Value |
|---|---|
| Application name | Musingly Local Dev |
| Homepage URL | http://localhost:3000 |
| Application description | Local development OAuth app |
| Authorization callback URL | http://localhost:54321/auth/v1/callback |
- Click Register application
Step 2: Generate Client Secret¶
- On the app page, click Generate a new client secret
- Copy and save both Client ID and Client Secret immediately
- The secret is only shown once!
Example credentials:
Step 3: (Optional) Upload App Logo¶
- On the OAuth app page, click Upload new logo
- Upload a square image (recommended: 512x512px)
- This appears on the OAuth consent screen
Environment Configuration¶
Step 1: Create .env File¶
Create a .env file in the project root with your OAuth credentials:
# ============================================
# SUPABASE CONFIGURATION
# ============================================
SUPABASE_URL=http://127.0.0.1:54321
SUPABASE_PUBLISHABLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0
SUPABASE_SECRET_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU
# ============================================
# AUTH CONFIGURATION
# ============================================
AUTH_SITE_URL=http://localhost:3000
AUTH_REDIRECT_URLS=http://localhost:3000/callback,http://localhost:3000/auth/callback
AUTH_CALLBACK_URL=http://localhost:54321/auth/v1/callback
# JWT/Session Settings
AUTH_JWT_EXPIRY=3600
AUTH_REFRESH_TOKEN_EXPIRY=604800
AUTH_SESSION_TIMEOUT=86400
# Signup Settings
AUTH_ENABLE_SIGNUP=true
AUTH_ENABLE_EMAIL_SIGNUP=true
AUTH_ENABLE_EMAIL_CONFIRMATIONS=false
# ============================================
# GOOGLE OAUTH
# ============================================
AUTH_GOOGLE_ENABLED=true
GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-your-google-client-secret
# ============================================
# GITHUB OAUTH
# ============================================
AUTH_GITHUB_ENABLED=true
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
# ============================================
# DEVELOPMENT OPTIONS
# ============================================
DEV_BYPASS_AUTH=false
LOG_LEVEL=debug
ENVIRONMENT=development
Step 2: Verify .env.example¶
Ensure .env.example is up to date for team reference (already configured in this repo).
Step 3: Add .env to .gitignore¶
Verify .env is in .gitignore (never commit secrets):
Supabase Configuration¶
Understanding config.toml¶
The supabase/config.toml file configures local Supabase services. OAuth providers are configured in the [auth.external.*] sections.
Current Configuration¶
The project is pre-configured with Google and GitHub OAuth. Verify the configuration:
# supabase/config.toml
[auth]
enabled = true
site_url = "http://localhost:3000"
additional_redirect_urls = ["https://localhost:3000"]
jwt_expiry = 3600
enable_signup = true
[auth.external.google]
enabled = true
client_id = "env(GOOGLE_CLIENT_ID)"
secret = "env(GOOGLE_CLIENT_SECRET)"
[auth.external.github]
enabled = true
client_id = "env(GITHUB_CLIENT_ID)"
secret = "env(GITHUB_CLIENT_SECRET)"
Environment Variable Binding¶
Supabase CLI reads OAuth credentials from environment variables using env(VAR_NAME) syntax:
| Config Key | Environment Variable |
|---|---|
client_id = "env(GOOGLE_CLIENT_ID)" |
GOOGLE_CLIENT_ID |
secret = "env(GOOGLE_CLIENT_SECRET)" |
GOOGLE_CLIENT_SECRET |
client_id = "env(GITHUB_CLIENT_ID)" |
GITHUB_CLIENT_ID |
secret = "env(GITHUB_CLIENT_SECRET)" |
GITHUB_CLIENT_SECRET |
Testing the Configuration¶
Step 1: Start Supabase¶
# Start all Supabase services
supabase start
# Expected output:
# Started supabase local development setup.
#
# API URL: http://127.0.0.1:54321
# GraphQL URL: http://127.0.0.1:54321/graphql/v1
# DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
# Studio URL: http://127.0.0.1:54323
# Inbucket URL: http://127.0.0.1:54324
Step 2: Apply Database Migrations¶
# Reset database and apply migrations
supabase db reset
# Verify tables exist
psql "postgresql://postgres:postgres@127.0.0.1:54322/postgres" -c "\dt"
Step 3: Serve Edge Functions¶
# Serve all edge functions
supabase functions serve
# Or serve only auth function
supabase functions serve auth
Step 4: Test OAuth Providers¶
Test Google OAuth¶
# 1. Get OAuth URL (will show redirect URL)
curl -v "http://127.0.0.1:54321/functions/v1/auth/auth/login?provider=google"
# 2. Open the redirect URL in browser
# 3. Complete Google sign-in
# 4. You'll be redirected to callback with code parameter
Test GitHub OAuth¶
# 1. Get OAuth URL
curl -v "http://127.0.0.1:54321/functions/v1/auth/auth/login?provider=github"
# 2. Open the redirect URL in browser
# 3. Complete GitHub authorization
# 4. You'll be redirected to callback with code parameter
Test Session Endpoint¶
# Check session (anonymous)
curl "http://127.0.0.1:54321/functions/v1/auth/auth/session"
# Expected response:
# {"authenticated":false,"user":null,"session":null}
Test Providers Endpoint¶
# List enabled providers
curl "http://127.0.0.1:54321/functions/v1/auth/auth/providers"
# Expected response:
# {"providers":["google","github"]}
Step 5: Verify in Supabase Studio¶
- Open http://127.0.0.1:54323
- Go to Authentication → Users
- After successful OAuth login, you should see the user
- Go to Table Editor → user_profiles to see profile data
Production Deployment¶
Step 1: Create Production OAuth Apps¶
Create separate OAuth apps for production with production URLs:
Google OAuth (Production):
- Authorized redirect URI: https://YOUR_PROJECT.supabase.co/auth/v1/callback
GitHub OAuth (Production):
- Authorization callback URL: https://YOUR_PROJECT.supabase.co/auth/v1/callback
Step 2: Configure Supabase Dashboard¶
- Go to Supabase Dashboard
- Select your project
- Go to Authentication → Providers
- Enable Google:
- Enter Client ID
- Enter Client Secret
- Save
- Enable GitHub:
- Enter Client ID
- Enter Client Secret
- Save
Step 3: Configure Redirect URLs¶
- Go to Authentication → URL Configuration
- Set Site URL:
https://your-app.com - Add Redirect URLs:
https://your-app.com/callbackhttps://your-app.com/auth/callback
Step 4: Deploy Edge Functions¶
# Deploy auth function
supabase functions deploy auth --project-ref YOUR_PROJECT_REF
# Set secrets
supabase secrets set GOOGLE_CLIENT_ID=prod-client-id --project-ref YOUR_PROJECT_REF
supabase secrets set GOOGLE_CLIENT_SECRET=prod-secret --project-ref YOUR_PROJECT_REF
supabase secrets set GITHUB_CLIENT_ID=prod-client-id --project-ref YOUR_PROJECT_REF
supabase secrets set GITHUB_CLIENT_SECRET=prod-secret --project-ref YOUR_PROJECT_REF
Troubleshooting¶
Common Issues¶
"Invalid client" or "OAuth failed"¶
Cause: Incorrect OAuth credentials or redirect URI mismatch
Solution:
1. Verify credentials in .env match exactly with OAuth provider dashboard
2. Check redirect URI is exactly: http://localhost:54321/auth/v1/callback
3. Ensure no trailing slashes in URLs
"Redirect URI mismatch"¶
Cause: The callback URL doesn't match configured redirect URIs
Solution:
1. Google: Add http://localhost:54321/auth/v1/callback to Authorized redirect URIs
2. GitHub: Set Authorization callback URL to http://localhost:54321/auth/v1/callback
"Access blocked: App not verified" (Google)¶
Cause: Google OAuth app is in testing mode
Solution: 1. Go to OAuth consent screen 2. Add your email under "Test users" 3. Or publish the app (requires verification for production)
"Provider not enabled"¶
Cause: OAuth provider not configured in Supabase
Solution:
1. Check supabase/config.toml has provider enabled
2. Verify environment variables are set
3. Restart Supabase: supabase stop && supabase start
"Failed to fetch user info"¶
Cause: OAuth scopes insufficient or API not enabled
Solution:
1. Google: Enable Google+ API in Cloud Console
2. Verify OAuth scopes include: openid, email, profile
Debug Commands¶
# View Supabase logs
supabase functions logs auth --follow
# Check Supabase status
supabase status
# Restart Supabase
supabase stop && supabase start
# Reset everything
supabase stop
supabase start
supabase db reset
Verify Environment Variables¶
# Check if env vars are loaded
deno eval "console.log({
google: !!Deno.env.get('GOOGLE_CLIENT_ID'),
github: !!Deno.env.get('GITHUB_CLIENT_ID')
})"
Security Best Practices¶
Local Development¶
- Never commit
.envfiles - Keep secrets out of version control - Use test OAuth apps - Separate from production
- Limit test users - Only add necessary emails in Google OAuth
Production¶
- Use separate OAuth apps - Never share credentials between environments
- Rotate secrets regularly - Update client secrets periodically
- Monitor OAuth usage - Check for suspicious activity
- Enable MFA - On developer accounts with OAuth access
- Restrict redirect URIs - Only add necessary URLs
Quick Reference¶
URLs¶
| Service | Local URL |
|---|---|
| Supabase API | http://127.0.0.1:54321 |
| Auth Callback | http://localhost:54321/auth/v1/callback |
| Supabase Studio | http://127.0.0.1:54323 |
| Inbucket (Email) | http://127.0.0.1:54324 |
Environment Variables¶
| Variable | Required | Description |
|---|---|---|
AUTH_GOOGLE_ENABLED |
Yes | Enable Google OAuth (true/false) |
GOOGLE_CLIENT_ID |
If Google enabled | Google OAuth Client ID |
GOOGLE_CLIENT_SECRET |
If Google enabled | Google OAuth Client Secret |
AUTH_GITHUB_ENABLED |
Yes | Enable GitHub OAuth (true/false) |
GITHUB_CLIENT_ID |
If GitHub enabled | GitHub OAuth Client ID |
GITHUB_CLIENT_SECRET |
If GitHub enabled | GitHub OAuth Client Secret |
API Endpoints¶
| Endpoint | Method | Description |
|---|---|---|
/auth/login?provider=google |
GET | Start Google OAuth |
/auth/login?provider=github |
GET | Start GitHub OAuth |
/auth/callback |
GET | OAuth callback handler |
/auth/session |
GET | Get current session |
/auth/logout |
POST | End session |
/auth/refresh |
POST | Refresh access token |
/auth/providers |
GET | List enabled providers |