Skip to content

Feature: OAuth/Social Login Providers Plugin #737

@lane711

Description

@lane711

Summary

Add OAuth/social login provider support as a plugin, allowing users to sign in via Google, GitHub, Discord, and other OAuth2 providers alongside the existing email/password auth.

Motivation

Community interest in replacing the built-in auth with Better Auth (#620) was primarily driven by wanting OAuth providers. Rather than a full auth rewrite (which would be a breaking change), we can add OAuth as a plugin on top of the existing hardened auth system.

The current auth stack is solid after the v2.8.3–v2.9.x security hardening:

Proposed Approach

Plugin: oauth-providers

Phase 1 — Core OAuth2 Flow

  • Generic OAuth2/OIDC authorization code flow
  • Provider-agnostic token exchange and user info fetching
  • Account linking (connect OAuth to existing email account)
  • New user creation from OAuth profile
  • Session management (reuse existing JWT system)
  • Admin settings UI for configuring provider credentials

Phase 2 — Built-in Providers

  • Google (accounts.google.com)
  • GitHub (github.com/login/oauth)
  • Discord (discord.com/oauth2)
  • Microsoft/Azure AD
  • Generic OIDC (for self-hosted identity providers)

Phase 3 — Advanced Features

  • TOTP/2FA support
  • Account linking management UI
  • Provider-specific scopes and permissions
  • JWT claims enrichment from OAuth profile

Auth Routes Added

GET  /auth/oauth/:provider          → Redirect to provider
GET  /auth/oauth/:provider/callback → Handle callback, create/link account
POST /auth/oauth/link               → Link OAuth to existing account
POST /auth/oauth/unlink             → Unlink OAuth provider

Database Changes

New oauth_accounts table:

CREATE TABLE oauth_accounts (
  id TEXT PRIMARY KEY,
  user_id TEXT NOT NULL REFERENCES users(id),
  provider TEXT NOT NULL,
  provider_account_id TEXT NOT NULL,
  access_token TEXT,
  refresh_token TEXT,
  token_expires_at INTEGER,
  created_at INTEGER NOT NULL,
  updated_at INTEGER NOT NULL,
  UNIQUE(provider, provider_account_id)
);

Admin UI

  • Settings page: configure client ID/secret per provider
  • User profile: show linked OAuth accounts
  • Login page: "Sign in with Google/GitHub/Discord" buttons

Design Principles

  • Plugin, not core — OAuth is optional, doesn't affect users who don't need it
  • No breaking changes — existing email/password auth unchanged
  • Cloudflare Workers compatible — no Node.js-specific dependencies
  • Minimal dependencies — use native fetch for OAuth flows, no heavy auth libraries

Prior Art / Inspiration

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions