Adding OAuth Providers
Add new OAuth providers or configure existing ones for user authentication
The SaaS starter kit uses Auth.js v5 for authentication with OAuth providers. GitHub and Google are configured by default, and you can easily add more providers like Twitter, LinkedIn, or Facebook.
Prerequisites
- Basic understanding of OAuth 2.0 flow
- Developer account with the OAuth provider (GitHub, Google, etc.)
- Familiarity with environment variables
How OAuth Works
When a user signs in with an OAuth provider:
- User clicks "Sign in with GitHub" (or Google, etc.)
- User is redirected to the provider's login page
- User authorizes your app to access their basic profile
- Provider redirects back to your app with a code
- Your app exchanges the code for user information
- User is authenticated and logged into your SaaS
Configuring Existing Providers
GitHub OAuth Setup
Create GitHub OAuth App
- Go to GitHub Developer Settings
- Click "New OAuth App"
- Fill in the application details:
- Application name: Your SaaS Name
- Homepage URL:
http://localhost:3000(dev) or your production URL - Authorization callback URL:
http://localhost:3000/api/auth/callback/github
- Click "Register application"
- Copy the Client ID
- Click "Generate a new client secret" and copy the secret
Add GitHub Credentials to Environment
1# GitHub OAuth2AUTH_GITHUB_ID="your-github-client-id"3AUTH_GITHUB_SECRET="your-github-client-secret"Automatic Enabling
Google OAuth Setup
Create Google OAuth App
- Go to Google Cloud Console
- Create a new project (or select existing)
- Navigate to "APIs & Services" â "Credentials"
- Click "Create Credentials" â "OAuth client ID"
- Configure OAuth consent screen if prompted
- Select "Web application" as application type
- Add authorized redirect URI:
http://localhost:3000/api/auth/callback/google
- Copy the Client ID and Client Secret
Add Google Credentials to Environment
1# Google OAuth2AUTH_GOOGLE_ID="your-google-client-id.apps.googleusercontent.com"3AUTH_GOOGLE_SECRET="your-google-client-secret"Adding New OAuth Providers
Auth.js supports 60+ OAuth providers. Here's how to add a new one (using Twitter/X as an example):
Install Provider (if needed)
Most providers are included in Auth.js. Check the provider list to see if yours is supported.
1# Usually no installation needed - providers are built-inAdd Provider to Feature Flags
Extend the feature detection system in src/lib/config/features.ts:
1export function getFeatures() {2 return {3 oauth: {4 github: {5 enabled: !!(6 process.env.AUTH_GITHUB_ID && process.env.AUTH_GITHUB_SECRET7 ),8 },9 google: {10 enabled: !!(11 process.env.AUTH_GOOGLE_ID && process.env.AUTH_GOOGLE_SECRET12 ),13 },14 // Add Twitter/X OAuth15 twitter: {16 enabled: !!(17 process.env.AUTH_TWITTER_ID && process.env.AUTH_TWITTER_SECRET18 ),19 },20 },21 };22}Configure Provider in Auth.js
Update src/lib/auth.ts to include the new provider:
1import NextAuth from "next-auth";2import GitHub from "next-auth/providers/github";3import Google from "next-auth/providers/google";4import Twitter from "next-auth/providers/twitter"; // Import new provider5import { PrismaAdapter } from "@auth/prisma-adapter";6import type { Provider } from "next-auth/providers";7 8import { prisma } from "@/lib/db";9import { getFeatures } from "@/lib/config/features";10 11function getProviders(): Provider[] {12 const providers: Provider[] = [];13 const { oauth } = getFeatures();14 15 if (oauth.github.enabled) {16 providers.push(17 GitHub({18 clientId: process.env.AUTH_GITHUB_ID!,19 clientSecret: process.env.AUTH_GITHUB_SECRET!,20 })21 );22 }23 24 if (oauth.google.enabled) {25 providers.push(26 Google({27 clientId: process.env.AUTH_GOOGLE_ID!,28 clientSecret: process.env.AUTH_GOOGLE_SECRET!,29 })30 );31 }32 33 // Add Twitter provider conditionally34 if (oauth.twitter.enabled) {35 providers.push(36 Twitter({37 clientId: process.env.AUTH_TWITTER_ID!,38 clientSecret: process.env.AUTH_TWITTER_SECRET!,39 })40 );41 }42 43 return providers;44}45 46export const { handlers, auth, signIn, signOut } = NextAuth({47 adapter: PrismaAdapter(prisma),48 session: { strategy: "database" },49 callbacks: {50 session: ({ session, user }) => ({51 ...session,52 user: { ...session.user, id: user.id },53 }),54 },55 providers: getProviders(),56});Add Environment Variables
Create an OAuth app on the provider's developer platform and add credentials:
1# Twitter OAuth2AUTH_TWITTER_ID="your-twitter-client-id"3AUTH_TWITTER_SECRET="your-twitter-client-secret"Update Login UI (Optional)
The login page automatically shows enabled providers. If you want custom styling, update the login page:
1import { getFeatures } from "@/lib/config/features";2 3export default function LoginPage() {4 const features = getFeatures();5 6 return (7 <div>8 {features.oauth.github.enabled && (9 <button>Sign in with GitHub</button>10 )}11 12 {features.oauth.google.enabled && (13 <button>Sign in with Google</button>14 )}15 16 {/* Add Twitter button */}17 {features.oauth.twitter.enabled && (18 <button>Sign in with Twitter</button>19 )}20 </div>21 );22}Understanding the Auth System
Auth.js Configuration
The authentication is configured in src/lib/auth.ts:
1export const { handlers, auth, signIn, signOut } = NextAuth({2 adapter: PrismaAdapter(prisma), // Database adapter for storing sessions3 session: {4 strategy: "database", // Sessions stored in database (not JWT)5 },6 callbacks: {7 session: ({ session, user }) => ({8 ...session,9 user: {10 ...session.user,11 id: user.id, // Add user ID to session12 },13 }),14 },15 providers: getProviders(), // Dynamically loaded providers16});Database Storage
OAuth connections are stored in the Account model:
1model Account {2 id String @id @default(cuid())3 userId String4 type String5 provider String // "github", "google", "twitter", etc.6 providerAccountId String // User's ID on the provider7 refresh_token String?8 access_token String?9 expires_at Int?10 11 user User @relation(fields: [userId], references: [id])12 13 @@unique([provider, providerAccountId])14}A user can connect multiple OAuth providers to the same account.
API Routes
Auth.js API routes are automatically created:
/api/auth/signin- Sign in page/api/auth/signout- Sign out endpoint/api/auth/callback/[provider]- OAuth callback handlers/api/auth/session- Get current session
These are defined in src/app/api/auth/[...nextauth]/route.ts:
1import { handlers } from "@/lib/auth";2 3export const { GET, POST } = handlers;Popular Provider Examples
Twitter / X
1import Twitter from "next-auth/providers/twitter";2 3Twitter({4 clientId: process.env.AUTH_TWITTER_ID!,5 clientSecret: process.env.AUTH_TWITTER_SECRET!,6})Create app at: Twitter Developer Portal
1import LinkedIn from "next-auth/providers/linkedin";2 3LinkedIn({4 clientId: process.env.AUTH_LINKEDIN_ID!,5 clientSecret: process.env.AUTH_LINKEDIN_SECRET!,6})Create app at: LinkedIn Developers
1import Facebook from "next-auth/providers/facebook";2 3Facebook({4 clientId: process.env.AUTH_FACEBOOK_ID!,5 clientSecret: process.env.AUTH_FACEBOOK_SECRET!,6})Create app at: Facebook for Developers
Discord
1import Discord from "next-auth/providers/discord";2 3Discord({4 clientId: process.env.AUTH_DISCORD_ID!,5 clientSecret: process.env.AUTH_DISCORD_SECRET!,6})Create app at: Discord Developer Portal
Troubleshooting
Provider Not Showing on Login Page
- Verify both Client ID and Client Secret are set in
.env.local - Restart dev server after adding environment variables
- Check
getFeatures()returnsenabled: truefor the provider - Ensure provider is added to
getProviders()insrc/lib/auth.ts
OAuth Error: Redirect URI Mismatch
- Verify callback URL in provider settings matches:
http://localhost:3000/api/auth/callback/[provider] - For production, update to:
https://yourdomain.com/api/auth/callback/[provider] - Ensure protocol (http vs https) matches exactly
Authentication Fails After Login
- Check database is running and accessible
- Verify
DATABASE_URLis set correctly - Ensure Prisma migrations are up to date:
npx prisma migrate deploy - Check browser console and server logs for errors
User Can't Link Multiple Providers
- Ensure user logs in with the same email across providers
- Auth.js automatically links accounts with matching emails
- Check
Accounttable to verify multiple provider entries for the user
Production Considerations
Update Callback URLs
When deploying to production, update OAuth app settings with production callback URLs:
1https://yourdomain.com/api/auth/callback/github2https://yourdomain.com/api/auth/callback/google3https://yourdomain.com/api/auth/callback/twitterSeparate Dev and Prod Apps
Consider creating separate OAuth apps for development and production to avoid callback URL conflicts.
Environment Variable Security
Store production OAuth credentials securely in your hosting platform's environment settings (Vercel, Railway, etc.). Never commit secrets to version control.
Related Guides
Next Steps
Now that you understand OAuth providers, you might want to:
- Learn about Feature Flags to control provider availability
- Explore User Management for managing user accounts
- Review Database Schema to understand authentication data storage