Social Sign-In
Sign in to Kindship using your Google, GitHub, or other existing accounts.
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
Supabase supports many OAuth providers:
- GitHub
- GitLab
- Bitbucket
- Azure
- Discord
- Slack
- And more...
Setting Up OAuth
Configure in Supabase Dashboard
- Go to Authentication → Providers
- Enable your desired provider (e.g., Google)
- Add your OAuth credentials:
- Client ID
- Client Secret
- Redirect URL:
https://your-project.supabase.co/auth/v1/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-project.supabase.co/auth/v1/callback - Development:
http://localhost:54321/auth/v1/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-project.supabase.co/auth/v1/callback
- Copy Client ID and Client Secret to Supabase
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 { getSupabaseServerClient } from '@kit/supabase/server-client';
import * as z from 'zod';
const OAuthProviderSchema = z.enum([
'google',
'github',
'gitlab',
'azure',
'facebook',
]);
export const signInWithOAuthAction = enhanceAction(
async (provider) => {
const client = getSupabaseServerClient();
const origin = process.env.NEXT_PUBLIC_SITE_URL!;
const { data, error } = await client.auth.signInWithOAuth({
provider,
options: {
redirectTo: `${origin}/auth/callback`,
},
});
if (error) throw error;
// Redirect to OAuth provider
redirect(data.url);
},
{
schema: OAuthProviderSchema,
}
);
OAuth Callback Handler
// app/auth/callback/route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
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) {
const cookieStore = cookies();
const supabase = createRouteHandlerClient({ cookies: () => cookieStore });
await supabase.auth.exchangeCodeForSession(code);
}
// Redirect to home page
return NextResponse.redirect(new URL('/home', request.url));
}
Customizing OAuth Flow
Scopes
Request specific permissions:
await client.auth.signInWithOAuth({
provider: 'google',
options: {
scopes: 'email profile https://www.googleapis.com/auth/calendar',
},
});
Query Parameters
Pass custom parameters:
await client.auth.signInWithOAuth({
provider: 'azure',
options: {
queryParams: {
prompt: 'consent',
access_type: 'offline',
},
},
});
Skip Browser Redirect
For mobile apps or custom flows:
const { data } = await client.auth.signInWithOAuth({
provider: 'google',
options: {
skipBrowserRedirect: true,
},
});
// data.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 client = getSupabaseServerClient();
const user = await requireAuth();
const { data, error } = await client.auth.linkIdentity({
provider,
});
if (error) throw error;
redirect(data.url);
},
{ schema: OAuthProviderSchema, auth: true }
);
Unlinking Providers
export const unlinkOAuthProviderAction = enhanceAction(
async ({ provider, identityId }) => {
const client = getSupabaseServerClient();
const { error } = await client.auth.unlinkIdentity({
identity_id: identityId,
});
if (error) throw error;
revalidatePath('/settings/security');
},
{
schema: z.object({
provider: z.string(),
identityId: z.string(),
}),
auth: true,
}
);
Viewing Linked Identities
import { getSupabaseServerClient } from '@kit/supabase/server-client';
export async function getLinkedIdentities() {
const client = getSupabaseServerClient();
const { data: { user } } = await client.auth.getUser();
return user?.identities || [];
}
User Data from OAuth
Accessing Provider Data
const { data: { user } } = await client.auth.getUser();
// User metadata from provider
const {
full_name,
avatar_url,
email,
} = user.user_metadata;
// Provider-specific data
const identities = user.identities || [];
const googleIdentity = identities.find(i => i.provider === 'google');
console.log(googleIdentity?.identity_data);
Storing Additional Data
export const completeOAuthProfileAction = enhanceAction(
async (data) => {
const client = getSupabaseServerClient();
const user = await requireAuth();
// Update user metadata
await client.auth.updateUser({
data: {
username: data.username,
bio: data.bio,
},
});
// Update profile in database
await client.from('profiles').upsert({
id: user.id,
username: data.username,
bio: data.bio,
avatar_url: user.user_metadata.avatar_url,
});
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
Sign-In Failed
If the social sign-in fails:
- Try again — Temporary issues sometimes resolve on retry
- Check the provider — Make sure you can sign in to Google/GitHub directly
- Clear cookies — Browser issues can cause problems
- Try another browser — Rule out browser-specific issues
Wrong Account Connected
If you accidentally connected the wrong Google/GitHub account:
- Sign in to Kindship using another method
- Go to Settings > Security
- Remove the incorrect account
- Add the correct account
Account Already Exists
If you see "Account already exists" when using social sign-in:
- You might have already created an account with that email
- Try signing in with email/password instead
- Use password reset if needed
Email Mismatch
The email from the provider must match your Kindship account email. If they differ, you may need to:
- Sign in with the matching email method
- Update your Kindship email
- Contact support for help
Security Tips
Keep Provider Account Secure
Your provider account becomes a key to Kindship. Make sure it's protected:
- Use a strong password
- Enable two-factor authentication
- Watch for suspicious activity
Don't Share Provider Access
Anyone with access to your Google or GitHub account could sign in to your Kindship account.
Review Connected Apps Regularly
Periodically check what apps are connected to your Google/GitHub accounts. Remove any you no longer use.
Multiple Accounts
If you have multiple Google or GitHub accounts:
- Make sure you select the right one when signing in
- Each provider account can only link to one Kindship account
- Sign out of other accounts if you keep connecting the wrong one
Next Steps
- Email & Password — Alternative sign-in method
- Magic Links — Passwordless option
- Account Overview — Full account management guide