# How Supabase Auth with Google OAuth Works in awesome-gpt-image-2

> Learn how Supabase Auth with Google OAuth works in awesome-gpt-image-2. Explore front-end client setup, provider sign-in, and server-side token verification for seamless user authentication.

- Repository: [苍何/awesome-gpt-image-2](https://github.com/freestylefly/awesome-gpt-image-2)
- Tags: deep-dive
- Published: 2026-09-08

---

**The awesome-gpt-image-2 repository implements Google OAuth through Supabase by configuring a front-end client with automatic session detection, triggering provider sign-in, and verifying tokens server-side using a service-role key to synchronize user profiles.**

The `awesome-gpt-image-2` project leverages Supabase's built-in OAuth capabilities to enable seamless Google authentication without custom auth servers. This architecture splits the authentication flow between a browser-based client that handles the OAuth redirect and a back-end API that validates tokens and maintains enriched user profile data. Understanding this implementation reveals how modern applications can securely integrate third-party identity providers while maintaining persistent, refreshable user sessions.

## Front-End Supabase Client Configuration

The browser-side authentication begins in [`src/supabaseClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/supabaseClient.js), which initializes a Supabase client when the required environment variables are present. The configuration enables automatic session management through specific auth options that handle the OAuth callback transparently.

```javascript
import { createClient } from '@supabase/supabase-js';

const supabase = isSupabaseConfigured
  ? createClient(supabaseUrl, supabaseAnonKey, {
      auth: {
        autoRefreshToken: true,
        detectSessionInUrl: true,
        persistSession: true,
      },
    })
  : null;

```

The **`detectSessionInUrl: true`** setting is critical for Google OAuth flow. When Google redirects back to the application after user consent, the access token appears in the URL fragment. Supabase automatically extracts this token, validates it, and creates a session stored in local storage. The **`persistSession: true`** option ensures the session survives page reloads, while **`autoRefreshToken: true`** handles token renewal automatically before expiration.

## Initiating Google Sign-In

To trigger authentication, the UI calls the Supabase client's `signIn` method with the Google provider identifier. This redirects the user to Google's OAuth 2.0 consent screen without requiring custom redirect handling code.

```javascript
import { supabase } from '@/supabaseClient';

export async function loginWithGoogle() {
  const { error } = await supabase.auth.signIn({ provider: 'google' });
  if (error) console.error('Google sign-in failed:', error.message);
}

```

After the user grants permission, Google redirects back to the application with an `access_token` (and optional `refresh_token`) appended to the URL fragment. Because the client configuration includes `detectSessionInUrl`, Supabase automatically processes this callback, creating a session object containing `session.user` and `session.access_token` that subsequent API calls use for authentication.

## Back-End Token Verification and Profile Synchronization

Protected API routes verify the Supabase token and maintain a local user profile using utilities from [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js). Every protected endpoint imports **`getAuthContext`** to validate the incoming request and ensure user data stays synchronized with Google account details.

```javascript
import { getAuthContext } from '../_lib/supabase.js';

export async function handler(req, res) {
  const { user, profile, error } = await getAuthContext(req);
  if (error) {
    res.status(401).json({ error: error });
    return;
  }
  res.json({ user, profile });
}

```

The **`getAuthContext`** function performs several critical operations:

1. **Instantiates an admin client** using the `SUPABASE_SERVICE_ROLE_KEY` to bypass row-level security and perform administrative operations
2. **Extracts the bearer token** from the `Authorization` header (`Authorization: Bearer <token>`)
3. **Validates the token** via `client.auth.getUser(token)` to confirm the session with Supabase's servers
4. **Synchronizes profile data** by calling `ensureProfileForUser`, which creates or updates a local `profiles` table row

The profile synchronization logic in [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js) (lines 78-89) specifically handles Google metadata through the **`profilePayloadFromUser`** helper:

```javascript
function profilePayloadFromUser(user, existingProfile) {
  const metadata = user.user_metadata || {};
  const email = String(user.email || existingProfile?.email || '').trim().toLowerCase();
  const googleName = metadata.full_name || metadata.name || null;
  const googleAvatar = metadata.avatar_url || metadata.picture || null;

  return {
    id: user.id,
    email,
    full_name: existingProfile?.full_name || googleName,
    avatar_url: googleAvatar || existingProfile?.avatar_url || null,
    // other fields …
  };
}

```

This function pulls Google-specific metadata including the user's name and avatar URL from `user.user_metadata`, preferring existing profile values while ensuring Google data populates new accounts. The helper also links the profile to `user_memberships` records when applicable, enabling paid plan verification alongside authentication.

## Session Persistence and Protected Routes

The front-end automatically includes the stored bearer token in the `Authorization` header for subsequent API requests. Because the Supabase client persists the session to localStorage, users remain authenticated across browser sessions without re-authenticating with Google.

On the server side, routes like [`api/me.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/me.js) rely on `getAuthContext` to re-authenticate each request independently. This stateless verification approach ensures that revoked tokens are detected immediately, while the `normalizeProfile` function assembles the final user object returned to the frontend, combining Supabase auth data, Google metadata, and local membership status.

## Summary

- **[`src/supabaseClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/supabaseClient.js)** initializes the browser client with `detectSessionInUrl: true` to automatically handle Google OAuth callbacks
- **`supabase.auth.signIn({ provider: 'google' })`** triggers the OAuth flow without custom redirect logic
- **[`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js)** provides `getAuthContext` for server-side token validation using the service-role key
- **`profilePayloadFromUser`** extracts Google metadata (name, avatar) from `user.user_metadata` into the local `profiles` table
- **`persistSession: true`** enables long-lived sessions that survive page reloads while maintaining secure token refresh capabilities

## Frequently Asked Questions

### How does the front-end detect the Google OAuth callback?

The Supabase client configuration in [`src/supabaseClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/supabaseClient.js) sets **`detectSessionInUrl: true`**, which instructs the library to automatically scan the URL fragment for access tokens when the page loads. When Google redirects back to the application after authentication, Supabase extracts the token from the URL, validates it, and establishes a session without requiring custom parsing logic in the application code.

### What environment variables are required for Supabase Auth with Google OAuth?

The implementation requires **`VITE_SUPABASE_URL`** and **`VITE_SUPABASE_ANON_KEY`** for the front-end client initialization, which handle the public OAuth flow. The back-end requires **`SUPABASE_SERVICE_ROLE_KEY`** to create an admin client capable of verifying tokens and upserting user profiles in the database. These variables must be present at build time for the client and at runtime for the API routes.

### How does the back-end verify the Supabase access token?

Protected routes call **`getAuthContext`** from [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js), which extracts the bearer token from the `Authorization` header and passes it to **`client.auth.getUser(token)`**. This method validates the token against Supabase's authentication servers using the service-role client. Invalid or expired tokens result in an error response, while valid tokens return the user object and trigger profile synchronization.

### Where does awesome-gpt-image-2 store Google user metadata?

Google profile data (full name, avatar URL) resides in **`user.user_metadata`** returned by Supabase after OAuth authentication. The `profilePayloadFromUser` function in [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js) maps these values to the local `profiles` table, specifically extracting `metadata.full_name` or `metadata.name` for the display name and `metadata.avatar_url` or `metadata.picture` for the profile image URL.