# How to Set Up Supabase Authentication in awesome-gpt-image-2: Client and Server Configuration

> Learn to set up Supabase authentication for awesome-gpt-image-2. Configure environment variables, initialize the client, and protect server routes for secure access.

- Repository: [苍何/awesome-gpt-image-2](https://github.com/freestylefly/awesome-gpt-image-2)
- Tags: how-to-guide
- Published: 2026-09-13

---

**Configure `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY` in your environment, then initialize the browser client via [`src/supabaseClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/supabaseClient.js) and protect API routes using the server-side helpers exported from [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js).**

The **awesome-gpt-image-2** repository by freestylefly implements a split authentication architecture that handles user sessions in the browser while verifying identities on the server. This guide walks you through wiring up the Supabase JavaScript client, setting the required environment variables, and securing your API endpoints using the built-in authentication helpers.

## Configure Environment Variables

Create a `.env` file at the repository root based on the provided template. The project requires two client-side variables and one optional server-side variable:

```text
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-public-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-secret

```

The `VITE_` prefix allows Vite to expose these variables to the client bundle via `import.meta.env`. The `SUPABASE_SERVICE_ROLE_KEY` bypasses Row Level Security and should never reach the browser; it is used exclusively by serverless functions.

## Initialize the Browser Client

The file [`src/supabaseClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/supabaseClient.js) bootstraps the Supabase client for the React frontend. It validates that both environment variables exist before calling `createClient` to prevent runtime crashes in unconfigured environments.

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

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

export const isSupabaseConfigured = Boolean(supabaseUrl && supabaseAnonKey);

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

```

**Key features of this configuration:**
- **autoRefreshToken** automatically refreshes the JWT before it expires.
- **detectSessionInUrl** captures the session hash when users return from external OAuth providers.
- **persistSession** stores the session in `localStorage` for continuity across page reloads.

## Set Up Server-Side Authentication

Serverless API routes import helpers from [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js) to validate incoming requests and perform administrative actions. This module exports three critical functions:

- **`getAuthContext(req)`** extracts the JWT from the `Authorization` header or cookie, validates it against Supabase, and returns an object containing `user` and `session`.
- **`getSupabaseAdminClient()`** returns a privileged Supabase client initialized with `SUPABASE_SERVICE_ROLE_KEY`. Use this client only for internal operations that require bypassing security policies.
- **`isSupabaseServerConfigured()`** verifies that the service role key is present before attempting to create the admin client.

Example usage inside an API route:

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

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

  const adminClient = getSupabaseAdminClient();
  // Perform privileged operations here
}

```

## Secure API Routes

The repository protects sensitive endpoints—such as [`api/me.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/me.js), [`api/generation/status.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generation/status.js), and the `api/billing` routes—by invoking `getAuthContext` at the top of each handler. This pattern ensures that only valid Supabase sessions can access user-specific data or trigger credit-consuming operations.

```javascript
const { user } = await getAuthContext(req);
if (!user) return res.status(401).json({ error: 'unauthenticated' });

```

If the JWT is near expiration, the server-side validation automatically coordinates with the client-side refresh logic, maintaining a seamless user experience.

## Implement Authentication in the UI

With the client initialized, React components can trigger OAuth flows and retrieve the current user. The following example initiates a Google sign-in:

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

async function signInWithGoogle() {
  const { error } = await supabase.auth.signInWithOAuth({ 
    provider: 'google' 
  });
  if (error) console.error('Auth error:', error);
}

```

After successful authentication, retrieve the user object anywhere in your component tree:

```javascript
const { data: { user } } = await supabase.auth.getUser();

```

## Summary

- **Environment setup** requires `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY` for the browser, plus `SUPABASE_SERVICE_ROLE_KEY` for server-side admin tasks.
- **Client initialization** happens in [`src/supabaseClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/supabaseClient.js), which exports `isSupabaseConfigured` and a `createClient` instance with automatic token refresh and session persistence.
- **Server helpers** in [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js) provide `getAuthContext` for request validation and `getSupabaseAdminClient` for privileged database access.
- **API protection** is implemented by destructuring `user` from `getAuthContext` and returning a 401 response when authentication is missing.
- **UI integration** uses the exported `supabase` client to initiate OAuth flows and fetch the current session.

## Frequently Asked Questions

### What environment variables are required for Supabase authentication in this project?

You must define `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY` for the client to function. For server-side operations that bypass Row Level Security, add `SUPABASE_SERVICE_ROLE_KEY`. All variables are listed in `.env.example` at the repository root.

### How does the server verify the JWT token from the client?

The `getAuthContext` function in [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js) extracts the token from the `Authorization` header or cookie and validates it against the Supabase Auth API. It returns the authenticated user object or null if the token is invalid or expired.

### What is the difference between the anon key and the service role key?

The **anon key** (used in [`src/supabaseClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/supabaseClient.js)) is a public identifier that respects Row Level Security policies. The **service role key** (used in `getSupabaseAdminClient()`) is a secret key that grants full database access and must never be exposed to the browser.

### How do I check if Supabase is configured before initializing the client?

Import `isSupabaseConfigured` from [`src/supabaseClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/supabaseClient.js). This boolean evaluates to `true` only when both `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY` are present, allowing you to conditionally render authentication UI or skip Supabase-dependent logic during development.