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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions