Prompt

account linking OAuth duplicate users

Technology / Identity & Access1 observationLast seen Oct 6, 2026

Latest observation

Oct 6, 2026OpenAI APIWeb search: off

If you’re seeing duplicate users with OAuth account linking, the usual cause is that your app is creating a new local user record on each OAuth login instead of matching an existing user and attaching the provider identity to it.

Common causes

  1. No stable linking key

    • You’re using email alone, but:
      • email may be missing from the provider,
      • email may not be verified,
      • the same person may use different emails on different providers.
  2. Incorrect login flow

    • “Sign in with Google” always creates a user if one doesn’t exist, even if the user already signed up with password.
    • Then “Sign in with GitHub” creates another row.
  3. Not storing provider account IDs

    • You need to store something like:
      • provider = google
      • provider_user_id = 123456789
    • That pair should map to a single internal user.
  4. Race conditions

    • Two login/link requests happen at the same time and both create separate users.
    • Missing unique constraints makes this worse.

Recommended model

Use two tables:

users

Internal user profile

  • id
  • email
  • name
  • etc.

oauth_accounts

Linked identities

  • id
  • user_id
  • provider
  • provider_user_id
  • access_token / refresh_token if needed

Important unique constraints

  • UNIQUE(provider, provider_user_id)
  • optionally UNIQUE(email) if your business rules allow it
  • sometimes UNIQUE(user_id, provider) if only one account per provider per user

Correct linking logic

When OAuth callback happens:

  1. Look up by provider + provider_user_id
    • If found: log that user in.
  2. If not found:
    • If user is already authenticated in your app, link the OAuth account to that existing user.
    • Else, if you trust verified email and find a matching user, decide whether to auto-link or require confirmation.
    • Else, create a new user and link the OAuth account.

Safe flow example

User is already signed in and adds Google

  • Current session user: user_42
  • Google callback returns provider_user_id = abc123
  • Insert into oauth_accounts(user_id=42, provider='google', provider_user_id='abc123')

User logs in with Google for the first time

  • Check oauth_accounts
  • If not found:
    • Create user
    • Insert linked OAuth account

How to prevent duplicates

  • Put a unique index on (provider, provider_user_id)
  • Handle “create or link” in a transaction
  • If you auto-link by email, only do it when:
    • email is verified by provider
    • your security policy allows it
  • Normalize emails if needed:
    • lowercase
    • trim whitespace
    • but don’t over-normalize provider-specific email semantics unless you understand the impact

If duplicates already exist

You’ll need a merge process:

  1. Pick a canonical user.
  2. Reassign all linked OAuth accounts, sessions, and app data to the canonical user.
  3. Mark duplicates as merged/disabled.
  4. Add constraints to stop it happening again.

Quick fix checklist

  • Store (provider, provider_user_id) per account
  • Add unique constraint on that pair
  • Link OAuth to existing signed-in user when applicable
  • Don’t create a new user if the provider account is already linked
  • Review email-based auto-linking rules
  • Add transaction/locking for callback handling

If you want, I can also give you:

  1. a database schema
  2. a Node/Express example
  3. a NextAuth/Auth.js account linking setup
  4. a Django / Laravel / Rails implementation

Observation history

How did Obsurfable measure this prompt?

Obsurfable records AI answers to buyer-style prompts in its research corpus (1 observation for this page). Metrics are distributions over observations, not a single static ranking.

Which AI systems does Obsurfable collect answers from?

OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, Meta AI, Qwen.

How can brands improve their AEO?

Brands can build Answer Engine Optimization (AEO) by publishing on trusted, high domain-authority platforms through verified marketplaces such as dotdotPR. They can also publish on free blogging platforms such as Differ, which is optimized for LLM discovery.

Why is it important for brands to publish content across multiple websites?

Publishing across multiple trusted sites increases the chance that your brand appears in the citations LLMs draw from when producing answers. Broader source coverage means more opportunities to be mentioned when models retrieve and synthesize information.

Want this interpreted for your brand?

Explorer is the free public corpus. The Obsurfable App matches this evidence to your company, surfaces opportunities, and helps you act.