Add Discord Sign-In to Your App
Enable "Continue with Discord" for your application's users through OAuth42's social authentication feature.
What You'll Build
In this tutorial, you'll configure Discord as a social identity provider for your OAuth42 application. Your users will be able to click "Continue with Discord" and authenticate using their Discord account.
How it works:
- User clicks "Continue with Discord" in your app
- OAuth42 redirects to Discord for authentication
- Discord authenticates the user and returns to OAuth42
- OAuth42 creates/links the user account and issues tokens to your app
- Your app receives the tokens and the user is logged in
Perfect for gaming & communities: Discord has over 150 million monthly active users, making it an excellent authentication option especially for gaming, community-focused, and developer-oriented applications.
Prerequisites
- An OAuth42 account with an existing application
- A Discord account with access to the Developer Portal
- Your application already integrated with OAuth42 (see Getting Started with Hosted Auth)
Step 1: Create a Discord Application
- Go to Discord Developer Portal and log in
- Click New Application
- Enter your application name
- Accept the Discord Developer Terms of Service
- Click Create
Tip: Your Discord application name will be shown to users during the OAuth authorization screen, so choose something recognizable.
Step 2: Configure OAuth2 Settings
- In your application's settings, click OAuth2 in the left sidebar
- Under Redirects, click Add Redirect
- Add the OAuth42 callback URLs:
- Production:
https://api.oauth42.com/api/social-auth/callback - Development:
https://localhost:8443/api/social-auth/callback
- Production:
- Click Save Changes
Required Scopes
Discord's OAuth2 URL Generator shows many available scopes. For OAuth42 authentication, you only need to select two scopes:
identify- Access user's username, avatar, and discriminatoremail- Access user's email address (required for account creation)
Do not select other scopes like bot, guilds, connections, or openid - these are not needed for authentication and would request unnecessary permissions from your users.
Step 3: Get Application Credentials
- Still on the OAuth2 page
- Copy your Client ID
- Click Reset Secret to generate a client secret (or copy existing if available)
- Copy the Client Secret - you won't be able to see it again!
Keep your Client Secret safe! Never expose your Client Secret in client-side code or public repositories. Discord will not show it again after you navigate away.
Step 4: Configure Discord in OAuth42 Portal
Now configure Discord as a social provider in your OAuth42 application:
- Log in to the OAuth42 Portal
- Navigate to Applications and select your application
- Click the Social Providers tab
- Click Add Provider
- Select Discord from the dropdown
- Enter the Client ID you copied from Discord
- Enter the Client Secret you copied from Discord
- Click Add Provider to save
Secure Storage: Your Discord Client Secret is automatically encrypted with AES-256 before being stored. It's never logged or exposed in plain text.
Step 5: Add Discord Sign-In Button to Your App
If you're using OAuth42's hosted auth pages, the Discord Sign-In button appears automatically when you enable the provider. No code changes needed!
For custom login pages, add a Discord Sign-In button that initiates the social auth flow:
"use client"
import { useState } from 'react'
export default function LoginPage() {
const [isLoading, setIsLoading] = useState(false)
const handleDiscordSignIn = async () => {
setIsLoading(true)
// Call OAuth42's social auth init endpoint
const response = await fetch('/api/auth/social/discord', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
provider: 'discord',
client_id: process.env.NEXT_PUBLIC_OAUTH42_CLIENT_ID,
is_signup: true, // Allow account creation
}),
})
const data = await response.json()
if (data.authorization_url) {
// Redirect to Discord
window.location.href = data.authorization_url
}
}
return (
<div className="min-h-screen flex items-center justify-center bg-gray-100">
<div className="max-w-md w-full space-y-6 p-8 bg-white rounded-lg shadow">
<h1 className="text-2xl font-bold text-center">Sign In</h1>
<button
onClick={handleDiscordSignIn}
disabled={isLoading}
className="w-full flex items-center justify-center gap-3 py-3 px-4 bg-[#5865F2] text-white rounded-lg hover:bg-[#4752C4] transition-colors"
>
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/>
</svg>
{isLoading ? 'Redirecting...' : 'Continue with Discord'}
</button>
<div className="relative">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-gray-300" />
</div>
<div className="relative flex justify-center text-sm">
<span className="px-2 bg-white text-gray-500">or</span>
</div>
</div>
{/* Your regular email/password login form */}
<form className="space-y-4">
<input
type="email"
placeholder="Email"
className="w-full px-4 py-3 border border-gray-300 rounded-lg"
/>
<input
type="password"
placeholder="Password"
className="w-full px-4 py-3 border border-gray-300 rounded-lg"
/>
<button
type="submit"
className="w-full py-3 px-4 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700"
>
Sign In
</button>
</form>
</div>
</div>
)
}Brand guidelines: Discord's brand color is "Blurple" (#5865F2). Use "Continue with Discord" as the button text. See Discord's Brand Guidelines for design requirements.
Step 6: Create API Route for Social Auth (Custom Login Only)
If using a custom login page, create an API route to initiate the social auth flow:
mkdir -p app/api/auth/social/discord
touch app/api/auth/social/discord/route.tsAdd the following code to app/api/auth/social/discord/route.ts:
import { NextRequest, NextResponse } from 'next/server'
const API_BASE_URL = process.env.OAUTH42_ISSUER || 'https://api.oauth42.com'
export async function POST(request: NextRequest) {
try {
const body = await request.json()
const response = await fetch(`${API_BASE_URL}/api/social-auth/init`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
provider: 'discord',
client_id: body.client_id,
is_signup: body.is_signup || true,
state: body.state,
}),
})
const data = await response.json()
if (!response.ok) {
return NextResponse.json(data, { status: response.status })
}
return NextResponse.json(data)
} catch (error) {
console.error('[Social Auth] Error:', error)
return NextResponse.json(
{ error: 'Failed to initiate social auth' },
{ status: 500 }
)
}
}Using Hosted Auth? Skip this step! OAuth42's hosted auth pages automatically include the Discord Sign-In button when you enable the provider.
Step 7: Test Discord Sign-In
- Start your application
- Navigate to your login page
- Click "Continue with Discord"
- You'll be redirected to Discord's authorization page
- Sign in and authorize the application
- Discord redirects back to OAuth42
- OAuth42 creates/links your user and redirects to your app
- You're now logged in!
Success! Your users can now sign in with their Discord accounts.
How Account Linking Works
OAuth42 intelligently handles user accounts based on their Discord profile:
New User (Signup)
A new user account is created with their Discord profile info (username, email, avatar). A verified email address is required.
Existing Discord User (Login)
If the Discord account ID is already linked to a user, they're logged into that existing account.
Existing Email User
If a user with the same email already exists (from email/password signup or another provider), the Discord account is linked to that existing account.
Multiple Social Providers
Users can link multiple social providers (Google, Apple, Facebook, GitHub, GitLab, LinkedIn, Discord, X) to the same account, giving them flexibility in how they sign in.
Security Considerations
- OAuth 2.0: Discord uses standard OAuth 2.0 for authentication
- State Parameter: CSRF protection via cryptographically random state tokens
- Encrypted Storage: Discord Client Secrets are encrypted at rest using AES-256
- Email Verification: OAuth42 requires a verified email from Discord to create accounts
- Scopes: Only
identifyandemailscopes are requested - no access to servers or messages
Troubleshooting
"Invalid OAuth2 redirect_uri" error
The callback URL isn't configured correctly. Go to Discord Developer Portal → OAuth2 → Redirects and add the exact OAuth42 callback URL: https://api.oauth42.com/api/social-auth/callback
"Discord social login not configured" error
The Discord OAuth credentials are not configured for this application. Go to the OAuth42 Portal → Applications → Your App → Social Providers tab and verify that Discord is configured with valid credentials.
"Failed to authenticate with Discord" error
This usually means the Client ID or Client Secret is incorrect. Double-check your credentials in both the Discord Developer Portal and OAuth42 Portal.
"Discord did not provide email" error
The user's Discord account doesn't have a verified email. Users need to verify their email address in Discord settings, or sign up using email/password instead.
"Discord email is not verified" error
OAuth42 requires verified emails for security. The user needs to verify their email in Discord (Settings → My Account → Email).
Next Steps
- Add Google Sign-In - Enable Sign in with Google
- Add GitHub Sign-In - Enable Sign in with GitHub
- Add Facebook Sign-In - Enable Sign in with Facebook
- Add Apple Sign-In - Enable Sign in with Apple for webapp and iOS
- Add MFA for extra security
- Security best practices
Need Help?
Having trouble with Discord Sign-In? Check our documentation or reach out to support.