Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/eggarcia98/auth-backend/llms.txt

Use this file to discover all available pages before exploring further.

Auth Backend supports OAuth 2.0 via Supabase for both Google and Apple. The implementation uses the PKCE (Proof Key for Code Exchange) flow, which is the recommended approach for public clients such as single-page applications.

Why PKCE?

PKCE eliminates the need for a client secret in the browser by replacing it with a dynamically generated, cryptographically random code verifier. Each authorization request produces a unique verifier, which is stored server-side by Supabase. The provider receives only a hashed version (the code challenge). When the backend exchanges the authorization code for tokens, Supabase validates the code against the stored verifier — so intercepting the code alone is useless.

Code interception protection

An intercepted authorization code cannot be exchanged without the matching verifier.

No client secret

SPAs never need to embed a client secret — the code verifier serves the same purpose.

Replay prevention

Authorization codes are single-use and bound to a specific verifier.

Dynamic per-request

Every login attempt uses a new, unique verifier generated by Supabase.

Full PKCE flow

1

Get the authorization URL

Call GET /api/v1/auth/oauth/:provider to fetch an authorization URL. Supabase generates the code verifier and challenge internally and returns a ready-to-use URL.
curl
curl https://your-domain.com/api/v1/auth/oauth/google
response
{
  "success": true,
  "data": {
    "url": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...&code_challenge=...&code_challenge_method=S256&..."
  }
}
2

Redirect the user

Redirect the browser to the URL returned in step 1. The user authenticates with the provider and grants the requested scopes.Scopes requested per provider:
  • Googleemail profile
  • Appleemail name
3

Provider redirects back

After the user authenticates, the provider redirects to:
FRONTEND_URL/auth/:provider/callback?code=AUTHORIZATION_CODE
Extract the code query parameter from the URL.
4

Exchange the code for a session

Post the authorization code to POST /api/v1/auth/oauth/:provider/callback. The backend calls supabase.auth.exchangeCodeForSession(code), which validates the code against the stored PKCE verifier and returns a session.
curl
curl -X POST https://your-domain.com/api/v1/auth/oauth/google/callback \
  -H "Content-Type: application/json" \
  -c cookies.txt \
  -d '{"code": "AUTHORIZATION_CODE_FROM_URL"}'
On success, accessToken and refreshToken are written to HTTP-only cookies and the response body includes the user and token details.
response
{
  "success": true,
  "data": {
    "user": {
      "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "email": "user@example.com",
      "emailVerified": true,
      "provider": "google",
      "createdAt": "2024-01-15T10:00:00.000Z",
      "updatedAt": "2024-01-15T10:00:00.000Z"
    },
    "tokens": {
      "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
      "expiresIn": 3600
    }
  },
  "message": "OAuth authentication successful, tokens set in cookies"
}

Frontend integration (TypeScript)

step-1-initiate.ts
// Step 1: get the provider authorization URL
const res = await fetch('/api/v1/auth/oauth/google');
const { data } = await res.json();

// Step 2: redirect the user to the provider
window.location.href = data.url;
step-2-callback.ts
// In your frontend callback route: FRONTEND_URL/auth/google/callback
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');

if (code) {
  const res = await fetch('/api/v1/auth/oauth/google/callback', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ code }),
    credentials: 'include', // required — sends and stores cookies
  });

  const result = await res.json();
  if (result.success) {
    // Tokens are now in HTTP-only cookies
    window.location.href = '/dashboard';
  }
}
Always pass credentials: 'include' when calling the callback endpoint from the browser. Without it, the browser will not store the HTTP-only cookies that contain the session tokens.

Provider setup

Google OAuth credentials

  1. Open the Google Cloud Console and create or select a project.
  2. Navigate to APIs & Services → Credentials and create an OAuth 2.0 Client ID (application type: Web application).
  3. Under Authorized redirect URIs, add your Supabase callback URL:
    https://<your-project>.supabase.co/auth/v1/callback
    
  4. Copy the Client ID and Client Secret.

Configure in Supabase

  1. In your Supabase project dashboard go to Authentication → Providers → Google.
  2. Enable the provider and paste the Client ID and Client Secret.
  3. Set the Authorized Client IDs if you are also targeting native mobile clients.

Environment

No additional environment variables are needed on the Auth Backend side — provider credentials are stored in Supabase.

Callback request body

FieldTypeRequiredDescription
codestringYesAuthorization code from the provider redirect URL

Error cases

ScenarioHTTP statusError message
Missing code in body400Authorization code is required
Invalid or expired code401Failed to authenticate with OAuth provider
Unsupported provider404Route not found

Build docs developers (and LLMs) love