Note: This is mock/placeholder content for demonstration purposes.
Allow users to sign in with their existing accounts from Google, GitHub, and other providers.
The auth service supports many OAuth providers:
https://your-app.com/auth/callbackhttps://your-app.com/auth/callbackhttp://localhost:3000/auth/callbackhttps://yourapp.comhttps://your-app.com/auth/callback'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>
);
}
'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,
}
);
// 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));
}
Request specific permissions:
await signInWithOAuth({
provider: 'google',
scopes: ['email', 'profile', 'https://www.googleapis.com/auth/calendar'],
});
Pass custom parameters:
await signInWithOAuth({
provider: 'azure',
queryParams: {
prompt: 'consent',
access_type: 'offline',
},
});
For mobile apps or custom flows:
const url = await signInWithOAuth({
provider: 'google',
skipRedirect: true,
});
// url contains the OAuth URL
// Handle redirect manually
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 }
);
export const unlinkOAuthProviderAction = enhanceAction(
async ({ provider, identityId }) => {
await unlinkOAuthProvider({
identityId,
});
revalidatePath('/settings/security');
},
{
schema: z.object({
provider: z.string(),
identityId: z.string(),
}),
auth: true,
}
);
import { getSession } from '@kit/auth/server';
export async function getLinkedIdentities() {
const session = await getSession();
return session?.user.identities || [];
}
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);
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 }
);
// config/auth.config.ts
export const authConfig = {
providers: {
emailPassword: true,
oAuth: ['google', 'github'],
},
};
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 />
)}
</>
);
}
Ensure redirect URIs match exactly:
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');
}
OAuth providers may rate limit requests: