OAuth
Sign in with Google, GitHub, and other OAuth providers.
Note: This is mock/placeholder content for demonstration purposes.
Allow users to sign in with their existing accounts from Google, GitHub, and other providers.
Supported Providers
The auth service supports many OAuth providers:
- GitHub
- GitLab
- Bitbucket
- Azure
- Discord
- Slack
- And more...
Setting Up OAuth
Configure OAuth Provider
- Configure your desired provider (e.g., Google) in your auth config
- Add your OAuth credentials:
- Client ID
- Client Secret
- Redirect URL:
https://your-app.com/auth/callback
Google OAuth Setup
- Go to Google Cloud Console
- Create a new project or select existing
- Enable Google+ API
- Create OAuth 2.0 credentials
- Add authorized redirect URIs:
- Production:
https://your-app.com/auth/callback - Development:
http://localhost:3000/auth/callback
- Production:
GitHub OAuth Setup
- Go to GitHub Settings → Developer Settings → OAuth Apps
- Click "New OAuth App"
- Fill in details:
- Application name: Your App
- Homepage URL:
https://yourapp.com - Authorization callback URL:
https://your-app.com/auth/callback
- Copy Client ID and Client Secret to your auth configuration
Implementation
OAuth Sign In Button
'use client';
import { signInWithOAuthAction } from '../_lib/actions';
export function OAuthButtons() {
const handleGoogleSignIn = async () => {
await signInWithOAuthAction('google');
};
const handleGitHubSignIn = async () => {
await signInWithOAuthAction('github');
};
return (
<div className="space-y-2">
<button
onClick={handleGoogleSignIn}
className="w-full flex items-center justify-center gap-2 border rounded-lg p-2"
>
<GoogleIcon />
Continue with Google
</button>
<button
onClick={handleGitHubSignIn}
className="w-full flex items-center justify-center gap-2 border rounded-lg p-2"
>
<GitHubIcon />
Continue with GitHub
</button>
</div>
);
}
Server Action
'use server';
import { enhanceAction } from '@kit/next/actions';
import * as z from 'zod';
const OAuthProviderSchema = z.enum([
'google',
'github',
'gitlab',
'azure',
'facebook',
]);
export const signInWithOAuthAction = enhanceAction(
async (provider) => {
const origin = process.env.NEXT_PUBLIC_SITE_URL!;
const url = await signInWithOAuth({
provider,
redirectTo: `${origin}/auth/callback`,
});
// Redirect to OAuth provider
redirect(url);
},
{
schema: OAuthProviderSchema,
}
);
OAuth Callback Handler
// app/auth/callback/route.ts
import { handleOAuthCallback } from '@kit/auth/server';
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
const requestUrl = new URL(request.url);
const code = requestUrl.searchParams.get('code');
if (code) {
await handleOAuthCallback(code);
}
// Redirect to home page
return NextResponse.redirect(new URL('/home', request.url));
}
Customizing OAuth Flow
Scopes
Request specific permissions:
await signInWithOAuth({
provider: 'google',
scopes: ['email', 'profile', 'https://www.googleapis.com/auth/calendar'],
});
Query Parameters
Pass custom parameters:
await signInWithOAuth({
provider: 'azure',
queryParams: {
prompt: 'consent',
access_type: 'offline',
},
});
Skip Browser Redirect
For mobile apps or custom flows:
const url = await signInWithOAuth({
provider: 'google',
skipRedirect: true,
});
// url contains the OAuth URL
// Handle redirect manually
Account Linking
Linking Additional Providers
Allow users to link multiple OAuth accounts:
export const linkOAuthProviderAction = enhanceAction(
async (provider) => {
const user = await requireAuth();
const url = await linkOAuthProvider({
userId: user.id,
provider,
});
redirect(url);
},
{ schema: OAuthProviderSchema, auth: true }
);
Unlinking Providers
export const unlinkOAuthProviderAction = enhanceAction(
async ({ provider, identityId }) => {
await unlinkOAuthProvider({
identityId,
});
revalidatePath('/settings/security');
},
{
schema: z.object({
provider: z.string(),
identityId: z.string(),
}),
auth: true,
}
);
Viewing Linked Identities
import { getSession } from '@kit/auth/server';
export async function getLinkedIdentities() {
const session = await getSession();
return session?.user.identities || [];
}
User Data from OAuth
Accessing Provider Data
import { getSession } from '@kit/auth/server';
const session = await getSession();
const user = session?.user;
// User metadata from provider
const {
name,
avatarUrl,
email,
} = user;
// Provider-specific data
const identities = user.identities || [];
const googleIdentity = identities.find(i => i.provider === 'google');
console.log(googleIdentity?.data);
Storing Additional Data
export const completeOAuthProfileAction = enhanceAction(
async (data) => {
const user = await requireAuth();
// Update user profile
await updateUserProfile({
userId: user.id,
username: data.username,
bio: data.bio,
avatarUrl: user.avatarUrl,
});
redirect('/home');
},
{ schema: ProfileSchema, auth: true }
);
Configuration
Enable OAuth in Config
// config/auth.config.ts
export const authConfig = {
providers: {
emailPassword: true,
oAuth: ['google', 'github'],
},
};
Conditional Rendering
import { authConfig } from '~/config/auth.config';
export function AuthProviders() {
return (
<>
{authConfig.providers.emailPassword && <EmailPasswordForm />}
{authConfig.providers.oAuth?.includes('google') && (
<GoogleSignInButton />
)}
{authConfig.providers.oAuth?.includes('github') && (
<GitHubSignInButton />
)}
</>
);
}
Troubleshooting
Redirect URI Mismatch
Ensure redirect URIs match exactly:
- Check auth configuration
- Verify OAuth app settings in provider console
- Use exact URLs (including http/https)
Missing Email
Some providers don't share email by default:
import { getSession } from '@kit/auth/server';
const session = await getSession();
if (!session?.user.email) {
// Request email separately or prompt user
redirect('/auth/complete-profile');
}
Rate Limiting
OAuth providers may rate limit requests:
- Cache OAuth tokens appropriately
- Don't make excessive authorization requests
- Handle rate limit errors gracefully
Best Practices
- Request minimum scopes - Only ask for what you need
- Handle errors gracefully - OAuth can fail for many reasons
- Verify email addresses - Some providers don't verify emails
- Support account linking - Let users connect multiple providers
- Provide fallback - Always offer email/password as backup
- Log OAuth events - Track sign-ins and linking attempts
- Test thoroughly - Test with real provider accounts