OAuth
Inicia sesión con Google, GitHub y otros proveedores de OAuth.
Nota: Este es contenido de ejemplo/marcador de posición con fines de demostración.
Permite que los usuarios inicien sesión con sus cuentas existentes de Google, GitHub y otros proveedores.
Proveedores compatibles
Supabase es compatible con muchos proveedores de OAuth:
- GitHub
- GitLab
- Bitbucket
- Azure
- Discord
- Slack
- Y muchos más...
Configuración de OAuth
Configurar en el panel de Supabase
- Ve a Authentication → Providers
- Activa el proveedor que quieras (por ejemplo, Google)
- Añade tus credenciales de OAuth:
- Client ID
- Client Secret
- Redirect URL:
https://your-project.supabase.co/auth/v1/callback
Configuración de OAuth de Google
- Ve a Google Cloud Console
- Crea un proyecto nuevo o selecciona uno existente
- Activa la API de Google+
- Crea credenciales de OAuth 2.0
- Añade los URI de redirección autorizados:
- Producción:
https://your-project.supabase.co/auth/v1/callback - Desarrollo:
http://localhost:54321/auth/v1/callback
- Producción:
Configuración de OAuth de GitHub
- Ve a GitHub Settings → Developer Settings → OAuth Apps
- Haz clic en "New OAuth App"
- Completa los datos:
- Application name: el nombre de tu aplicación
- Homepage URL:
https://yourapp.com - Authorization callback URL:
https://your-project.supabase.co/auth/v1/callback
- Copia el Client ID y el Client Secret en Supabase
Implementación
Botón de inicio de sesión con OAuth
'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 { 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;
// Redirigir al proveedor de OAuth
redirect(data.url);
},
{
schema: OAuthProviderSchema,
}
);
Controlador de callback de OAuth
// 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);
}
// Redirigir a la página de inicio
return NextResponse.redirect(new URL('/home', request.url));
}
Personalización del flujo de OAuth
Scopes
Solicita permisos específicos:
await client.auth.signInWithOAuth({
provider: 'google',
options: {
scopes: 'email profile https://www.googleapis.com/auth/calendar',
},
});
Parámetros de consulta
Pasa parámetros personalizados:
await client.auth.signInWithOAuth({
provider: 'azure',
options: {
queryParams: {
prompt: 'consent',
access_type: 'offline',
},
},
});
Omitir la redirección del navegador
Para aplicaciones móviles o flujos personalizados:
const { data } = await client.auth.signInWithOAuth({
provider: 'google',
options: {
skipBrowserRedirect: true,
},
});
// data.url contiene la URL de OAuth
// Gestiona la redirección manualmente
Vinculación de cuentas
Vincular proveedores adicionales
Permite que los usuarios vinculen varias cuentas de OAuth:
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 }
);
Desvincular proveedores
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,
}
);
Ver las identidades vinculadas
import { getSupabaseServerClient } from '@kit/supabase/server-client';
export async function getLinkedIdentities() {
const client = getSupabaseServerClient();
const { data: { user } } = await client.auth.getUser();
return user?.identities || [];
}
Datos del usuario obtenidos de OAuth
Acceder a los datos del proveedor
const { data: { user } } = await client.auth.getUser();
// Metadatos del usuario procedentes del proveedor
const {
full_name,
avatar_url,
email,
} = user.user_metadata;
// Datos específicos del proveedor
const identities = user.identities || [];
const googleIdentity = identities.find(i => i.provider === 'google');
console.log(googleIdentity?.identity_data);
Almacenar datos adicionales
export const completeOAuthProfileAction = enhanceAction(
async (data) => {
const client = getSupabaseServerClient();
const user = await requireAuth();
// Actualizar los metadatos del usuario
await client.auth.updateUser({
data: {
username: data.username,
bio: data.bio,
},
});
// Actualizar el perfil en la base de datos
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 }
);
Configuración
Activar OAuth en la configuración
// config/auth.config.ts
export const authConfig = {
providers: {
emailPassword: true,
oAuth: ['google', 'github'],
},
};
Renderizado condicional
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 />
)}
</>
);
}
Solución de problemas
Los URI de redirección no coinciden
Asegúrate de que los URI de redirección coincidan exactamente:
- Revisa Supabase Dashboard → Authentication → URL Configuration
- Verifica la configuración de la aplicación OAuth en la consola del proveedor
- Usa las URL exactas (incluido http/https)
Falta el correo electrónico
Algunos proveedores no comparten el correo electrónico de forma predeterminada:
const { data: { user } } = await client.auth.getUser();
if (!user.email) {
// Solicitar el correo electrónico por separado o pedírselo al usuario
redirect('/auth/complete-profile');
}
Limitación de solicitudes
Los proveedores de OAuth pueden limitar la frecuencia de las solicitudes:
- Almacena en caché los tokens de OAuth de forma adecuada
- No realices un número excesivo de solicitudes de autorización
- Gestiona correctamente los errores de límite de solicitudes
Buenas prácticas
- Solicita los scopes mínimos - Pide solo lo que necesites
- Gestiona los errores correctamente - OAuth puede fallar por muchos motivos
- Verifica las direcciones de correo electrónico - Algunos proveedores no verifican los correos electrónicos
- Admite la vinculación de cuentas - Permite que los usuarios conecten varios proveedores
- Ofrece una alternativa - Ofrece siempre correo electrónico/contraseña como respaldo
- Registra los eventos de OAuth - Haz un seguimiento de los inicios de sesión y los intentos de vinculación
- Haz pruebas exhaustivas - Prueba con cuentas reales de los proveedores