PriceLogicPriceLogic

The AI Platform for Marketplace Sellers

© Copyright 2025 PriceLogic, Inc. All Rights Reserved.

About
  • Blog
  • Contact
Product
  • Pricing
Legal
  • Terms of Service
  • Privacy Policy
  • Cookie Policy
  • Getting started with PriceLogic
    • Quick Start
    • Project Structure
    • Configuration
  • Diana API
  • Email & Password
  • Database
    • Database Overview
    • Migrations
    • Row Level Security
    • Querying Data
    • Functions & Triggers
  • OAuth
  • Features
    • Features Overview
    • Team Collaboration
    • File Uploads
  • Magic Links
  • Billing & Payments
    • Billing Overview
    • Pricing Plans
    • Webhook Integration

OAuth

Sign in with Google, GitHub, and other OAuth providers.

Note: This is mock/placeholder content for demonstration purposes.

Allow users to sign in with their existing accounts from Google, GitHub, and other providers.

Supported Providers

Supabase supports many OAuth providers:

  • Google
  • GitHub
  • GitLab
  • Bitbucket
  • Azure
  • Facebook
  • Twitter
  • Discord
  • Slack
  • And more...

Setting Up OAuth

Configure in Supabase Dashboard

  1. Go to Authentication → Providers
  2. Enable your desired provider (e.g., Google)
  3. Add your OAuth credentials:
    • Client ID
    • Client Secret
    • Redirect URL: https://your-project.supabase.co/auth/v1/callback

Google OAuth Setup

  1. Go to Google Cloud Console
  2. Create a new project or select existing
  3. Enable Google+ API
  4. Create OAuth 2.0 credentials
  5. Add authorized redirect URIs:
    • Production: https://your-project.supabase.co/auth/v1/callback
    • Development: http://localhost:54321/auth/v1/callback

GitHub OAuth Setup

  1. Go to GitHub Settings → Developer Settings → OAuth Apps
  2. Click "New OAuth App"
  3. Fill in details:
    • Application name: Your App
    • Homepage URL: https://yourapp.com
    • Authorization callback URL: https://your-project.supabase.co/auth/v1/callback
  4. Copy Client ID and Client Secret to Supabase

Implementation

OAuth Sign In Button

'use client';

import { signInWithOAuthAction } from '../_lib/actions';

export function OAuthButtons() {
  const handleGoogleSignIn = async () => {
    await signInWithOAuthAction('google');
  };

  const handleGitHubSignIn = async () => {
    await signInWithOAuthAction('github');
  };

  return (
    <div className="space-y-2">
      <button
        onClick={handleGoogleSignIn}
        className="w-full flex items-center justify-center gap-2 border rounded-lg p-2"
      >
        <GoogleIcon />
        Continue with Google
      </button>

      <button
        onClick={handleGitHubSignIn}
        className="w-full flex items-center justify-center gap-2 border rounded-lg p-2"
      >
        <GitHubIcon />
        Continue with GitHub
      </button>
    </div>
  );
}

Server Action

'use server';

import { enhanceAction } from '@kit/next/actions';
import { getSupabaseServerClient } from '@kit/supabase/server-client';
import { z } from 'zod';

const OAuthProviderSchema = z.enum([
  'google',
  'github',
  'gitlab',
  'azure',
  'facebook',
]);

export const signInWithOAuthAction = enhanceAction(
  async (provider) => {
    const client = getSupabaseServerClient();
    const origin = process.env.NEXT_PUBLIC_SITE_URL!;

    const { data, error } = await client.auth.signInWithOAuth({
      provider,
      options: {
        redirectTo: `${origin}/auth/callback`,
      },
    });

    if (error) throw error;

    // Redirect to OAuth provider
    redirect(data.url);
  },
  {
    schema: OAuthProviderSchema,
  }
);

OAuth Callback Handler

// app/auth/callback/route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
  const requestUrl = new URL(request.url);
  const code = requestUrl.searchParams.get('code');

  if (code) {
    const cookieStore = cookies();
    const supabase = createRouteHandlerClient({ cookies: () => cookieStore });

    await supabase.auth.exchangeCodeForSession(code);
  }

  // Redirect to home page
  return NextResponse.redirect(new URL('/home', request.url));
}

Customizing OAuth Flow

Scopes

Request specific permissions:

await client.auth.signInWithOAuth({
  provider: 'google',
  options: {
    scopes: 'email profile https://www.googleapis.com/auth/calendar',
  },
});

Query Parameters

Pass custom parameters:

await client.auth.signInWithOAuth({
  provider: 'azure',
  options: {
    queryParams: {
      prompt: 'consent',
      access_type: 'offline',
    },
  },
});

Skip Browser Redirect

For mobile apps or custom flows:

const { data } = await client.auth.signInWithOAuth({
  provider: 'google',
  options: {
    skipBrowserRedirect: true,
  },
});

// data.url contains the OAuth URL
// Handle redirect manually

Account Linking

Linking Additional Providers

Allow users to link multiple OAuth accounts:

export const linkOAuthProviderAction = enhanceAction(
  async (provider) => {
    const client = getSupabaseServerClient();
    const user = await requireAuth();

    const { data, error } = await client.auth.linkIdentity({
      provider,
    });

    if (error) throw error;

    redirect(data.url);
  },
  { schema: OAuthProviderSchema, auth: true }
);

Unlinking Providers

export const unlinkOAuthProviderAction = enhanceAction(
  async ({ provider, identityId }) => {
    const client = getSupabaseServerClient();

    const { error } = await client.auth.unlinkIdentity({
      identity_id: identityId,
    });

    if (error) throw error;

    revalidatePath('/settings/security');
  },
  {
    schema: z.object({
      provider: z.string(),
      identityId: z.string(),
    }),
    auth: true,
  }
);

Viewing Linked Identities

import { getSupabaseServerClient } from '@kit/supabase/server-client';

export async function getLinkedIdentities() {
  const client = getSupabaseServerClient();
  const { data: { user } } = await client.auth.getUser();

  return user?.identities || [];
}

User Data from OAuth

Accessing Provider Data

const { data: { user } } = await client.auth.getUser();

// User metadata from provider
const {
  full_name,
  avatar_url,
  email,
} = user.user_metadata;

// Provider-specific data
const identities = user.identities || [];
const googleIdentity = identities.find(i => i.provider === 'google');

console.log(googleIdentity?.identity_data);

Storing Additional Data

export const completeOAuthProfileAction = enhanceAction(
  async (data) => {
    const client = getSupabaseServerClient();
    const user = await requireAuth();

    // Update user metadata
    await client.auth.updateUser({
      data: {
        username: data.username,
        bio: data.bio,
      },
    });

    // Update profile in database
    await client.from('profiles').upsert({
      id: user.id,
      username: data.username,
      bio: data.bio,
      avatar_url: user.user_metadata.avatar_url,
    });

    redirect('/home');
  },
  { schema: ProfileSchema, auth: true }
);

Configuration

Enable OAuth in Config

// config/auth.config.ts
export const authConfig = {
  providers: {
    emailPassword: true,
    oAuth: ['google', 'github'],
  },
};

Conditional Rendering

import { authConfig } from '~/config/auth.config';

export function AuthProviders() {
  return (
    <>
      {authConfig.providers.emailPassword && <EmailPasswordForm />}

      {authConfig.providers.oAuth?.includes('google') && (
        <GoogleSignInButton />
      )}

      {authConfig.providers.oAuth?.includes('github') && (
        <GitHubSignInButton />
      )}
    </>
  );
}

Troubleshooting

Redirect URI Mismatch

Ensure redirect URIs match exactly:

  • Check Supabase Dashboard → Authentication → URL Configuration
  • Verify OAuth app settings in provider console
  • Use exact URLs (including http/https)

Missing Email

Some providers don't share email by default:

const { data: { user } } = await client.auth.getUser();

if (!user.email) {
  // Request email separately or prompt user
  redirect('/auth/complete-profile');
}

Rate Limiting

OAuth providers may rate limit requests:

  • Cache OAuth tokens appropriately
  • Don't make excessive authorization requests
  • Handle rate limit errors gracefully

Best Practices

  1. Request minimum scopes - Only ask for what you need
  2. Handle errors gracefully - OAuth can fail for many reasons
  3. Verify email addresses - Some providers don't verify emails
  4. Support account linking - Let users connect multiple providers
  5. Provide fallback - Always offer email/password as backup
  6. Log OAuth events - Track sign-ins and linking attempts
  7. Test thoroughly - Test with real provider accounts
  1. Supported Providers
    1. Setting Up OAuth
    2. Implementation
    3. Customizing OAuth Flow
    4. Account Linking
    5. User Data from OAuth
    6. Configuration
    7. Troubleshooting
    8. Best Practices