Overview
Auction Excellence uses Supabase Auth for authentication, providing secure JWT-based access to all API resources. Authentication is required for all API endpoints except public resources.
JWT Tokens Secure JSON Web Tokens with 1-hour expiry and automatic refresh
Multi-Tenant Auction-scoped access with role-based permissions
Row Level Security Database-enforced security policies on all tables
Real-time Auth WebSocket authentication for live features
Authentication Methods
Email & Password
The primary authentication method for Auction Excellence. Users sign up with email and password, then sign in to receive JWT tokens.
curl -X POST 'https://your-project.supabase.co/auth/v1/signup' \
-H "apikey: YOUR_ANON_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword123",
"data": {
"full_name": "John Smith"
}
}'
Response: {
"id" : "uuid-of-new-user" ,
"email" : "user@example.com" ,
"user_metadata" : {
"full_name" : "John Smith"
},
"created_at" : "2025-01-15T10:30:00Z"
}
curl -X POST 'https://your-project.supabase.co/auth/v1/token?grant_type=password' \
-H "apikey: YOUR_ANON_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "securepassword123"
}'
Response: {
"access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"token_type" : "bearer" ,
"expires_in" : 3600 ,
"expires_at" : 1705320600 ,
"refresh_token" : "v1.MjA..." ,
"user" : {
"id" : "uuid-of-user" ,
"email" : "user@example.com" ,
"user_metadata" : {
"full_name" : "John Smith"
}
}
}
curl -X POST 'https://your-project.supabase.co/auth/v1/logout' \
-H "apikey: YOUR_ANON_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response: 204 No Content
Password Reset
Users can request a password reset email and then update their password.
Request Reset Email
curl -X POST 'https://your-project.supabase.co/auth/v1/recover' \
-H "apikey: YOUR_ANON_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com"
}'
User Clicks Email Link
The email contains a link with a recovery token that redirects to your app.
Update Password
curl -X PUT 'https://your-project.supabase.co/auth/v1/user' \
-H "apikey: YOUR_ANON_KEY" \
-H "Authorization: Bearer RECOVERY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"password": "newSecurePassword456"
}'
Auction Excellence uses standard JWT tokens with custom claims for multi-tenant authorization.
Token Structure
Decoded Payload
{
"aud" : "authenticated" ,
"exp" : 1705320600 ,
"iat" : 1705317000 ,
"iss" : "https://your-project.supabase.co/auth/v1" ,
"sub" : "user-uuid-here" ,
"email" : "user@example.com" ,
"phone" : "" ,
"app_metadata" : {
"provider" : "email" ,
"providers" : [ "email" ]
},
"user_metadata" : {
"full_name" : "John Smith"
},
"role" : "authenticated" ,
"aal" : "aal1" ,
"amr" : [
{
"method" : "password" ,
"timestamp" : 1705317000
}
],
"session_id" : "session-uuid-here"
}
Key Claims
Claim Description subUser’s unique UUID (used for all database operations) expToken expiration timestamp (1 hour from issue) iatToken issue timestamp roleAlways authenticated for logged-in users aalAuthentication Assurance Level session_idUnique session identifier for this login
Token Refresh Flow
Access tokens expire after 1 hour. Use refresh tokens to obtain new access tokens without requiring the user to sign in again.
curl -X POST 'https://your-project.supabase.co/auth/v1/token?grant_type=refresh_token' \
-H "apikey: YOUR_ANON_KEY" \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "v1.MjA..."
}'
Response:
{
"access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"token_type" : "bearer" ,
"expires_in" : 3600 ,
"expires_at" : 1705324200 ,
"refresh_token" : "v1.MjB..."
}
Refresh tokens are single-use. After each refresh, store the new refresh token returned in the response.
Client SDK Handling
The Supabase client SDKs handle token refresh automatically:
import { createClient } from '@supabase/supabase-js'
const supabase = createClient (
'https://your-project.supabase.co' ,
'YOUR_ANON_KEY'
)
// Tokens are automatically refreshed
const { data : { session } } = await supabase . auth . getSession ()
import { createClient } from '@supabase/supabase-js'
import AsyncStorage from '@react-native-async-storage/async-storage'
const supabase = createClient (
'https://your-project.supabase.co' ,
'YOUR_ANON_KEY' ,
{
auth: {
storage: AsyncStorage ,
autoRefreshToken: true ,
persistSession: true
}
}
)
Using Tokens in API Requests
All authenticated API requests require the JWT token in the Authorization header.
curl -X GET 'https://your-project.supabase.co/rest/v1/locations' \
-H "apikey: YOUR_ANON_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json"
Header Required Description apikeyYes Your Supabase project’s anon key AuthorizationYes Bearer + your JWT access tokenContent-TypeFor POST/PUT Usually application/json
Multi-Tenant Authorization
Auction Excellence uses a multi-tenant architecture where users belong to one or more auctions (organizations). Authorization is enforced at multiple levels.
Auction Roles
Role Permissions ownerFull access, can transfer ownership, delete auction adminManage users, locations, settings; view all data team_memberSubmit data, view assigned locations
Authorization Flow
User Authenticates
User signs in and receives JWT token with their user_id
RLS Checks Membership
Row Level Security policies check auction_members table
Role Determines Access
User’s role in the auction determines what actions they can perform
Helper Functions
The API provides helper functions to check authorization:
-- Check if user is member of auction
SELECT is_auction_member( 'auction-uuid' );
-- Check if user is admin or above
SELECT is_auction_admin_or_above( 'auction-uuid' );
-- Get user's role in auction
SELECT get_user_auction_role( 'auction-uuid' );
Super Admin Access
Super admins have system-wide access across all auctions. This is a special privilege granted at the database level.
-- Check if current user is super admin
SELECT is_super_admin();
Super admin status is stored in the super_admins table and bypasses normal RLS policies.
Session Management
Get Current Session
curl -X GET 'https://your-project.supabase.co/auth/v1/user' \
-H "apikey: YOUR_ANON_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Update User Profile
curl -X PUT 'https://your-project.supabase.co/auth/v1/user' \
-H "apikey: YOUR_ANON_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"full_name": "John Smith Updated"
}
}'
Error Responses
Authentication errors return standard HTTP status codes with descriptive messages.
Common Errors
Status Error Description 400 invalid_grantInvalid email/password combination 400 user_already_existsEmail already registered 401 invalid_tokenJWT token is invalid or expired 401 not_authenticatedNo Authorization header provided 422 weak_passwordPassword doesn’t meet requirements 429 rate_limit_exceededToo many requests
{
"error" : "invalid_grant" ,
"error_description" : "Invalid login credentials"
}
Handling Token Expiration
When a token expires, you’ll receive a 401 response:
{
"message" : "JWT expired" ,
"status" : 401
}
Use the refresh token to obtain a new access token, or prompt the user to sign in again.
Security Best Practices
Mobile : Use secure storage (iOS Keychain, Android Keystore)
Web : Use HTTP-only cookies or secure localStorage
Never expose tokens in URLs or logs
All API requests must use HTTPS. HTTP requests will be rejected.
Implement automatic token refresh to prevent session interruption. The Supabase SDK handles this automatically.
Always validate tokens server-side. RLS policies enforce this automatically.
Rate Limiting
Authentication endpoints have rate limits to prevent abuse:
Endpoint Limit Sign In 30 requests per hour per IP Sign Up 5 requests per hour per IP Password Reset 5 requests per hour per email Token Refresh 60 requests per hour per user
Rate limit headers are included in responses:
X-RateLimit-Limit: Maximum requests allowed
X-RateLimit-Remaining: Requests remaining
X-RateLimit-Reset: Timestamp when limit resets
Next Steps