Autenticación con nextjs y supabase
Francisco Villarreal
Posted on March 2, 2024
En este artículo, exploraremos los pasos necesarios para crear una autenticación sólida utilizando la potencia de Next.js y la flexibilidad de Supabase. desglosaremos cada etapa del proceso para que puedas construir una autenticación escalable y confiable en tu aplicación web.
el proyecto completo po puedes encontrar en el repositorio auth_nextjs_supabase
Primero, inicializaremos el proyecto de Next.js desde la terminal ejecutando el siguiente comando:
npx create-next-app@latest
Este comando iniciará el proceso de configuración del proyecto de Next.js y te hará algunas preguntas básicas. Para este ejemplo, puedes seleccionar todas las opciones por defecto.
What is your project named? my-app
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like to use `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to customize the default import alias (@/*)? No / Yes
What import alias would you like configured? @/*
Una vez finalizada la instalación de todos los paquetes, procedemos a instalar las librerías de Supabase para establecer la conexión. Ejecuta el siguiente comando en la terminal:
npm install @supabase/auth-helpers-nextjs @supabase/supabase-js
Luego, recupera la URL y la clave anónima de tu proyecto desde la configuración de tu API settings. Crea un archivo .env.local
en la raíz del proyecto y declara las siguientes variables de entorno:
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key
Una vez creadas las variables de entorno, procedemos a activar los proveedores que deseamos habilitar para la autenticación. Para hacerlo, sigue estos pasos:
- Dentro del proyecto, dirígete a la sección de autenticación.
- Selecciona la opción "Providers".
- Habilita los proveedores que deseas utilizar.
- Para los proveedores que requieran cuentas de terceros, como Google o GitHub, deberás proporcionar un Client ID y un Client Secret. Estos se obtienen configurando la autenticación en la consola de desarrolladores de cada proveedor, siguiendo los pasos indicados para crear una nueva aplicación o proyecto. Una vez creada la aplicación, te proporcionarán el Client ID y el Client Secret que deberás ingresar en la configuración correspondiente de tu proyecto.
Repite este proceso para cada proveedor que desees habilitar, siguiendo las instrucciones específicas de cada plataforma para obtener las credenciales necesarias.
Nota: Antes de continuar, es importante verificar que la opción de
permitir a los usuarios crear nuevas cuentas esté disponible para ellos. Esto se puede hacer accediendo a la configuración del proyecto y navegando hasta el área de autenticación. Allí, asegúrate de habilitar la opción que permita a los usuarios crear nuevas cuentas. Esto garantizará que tengan la posibilidad de registrarse por sí mismos según sea necesario.
Middleware
Una vez completada toda la configuración, continuamos en nuestro proyecto de Next.js. En este paso, crearemos el archivo src/middleware.js
, donde desarrollaremos un middleware para verificar si el usuario ha iniciado sesión. Este middleware nos permitirá redirigir al usuario a la página principal si ya está autenticado, de lo contrario, lo dirigirá a la página de inicio de sesión.
import { createMiddlewareClient } from "@supabase/auth-helpers-nextjs";
import { NextRequest, NextResponse } from "next/server";
export async function middleware(req: NextRequest) {
const reqUrl = new URL(req.url);
const res = NextResponse.next();
const supabase = createMiddlewareClient({ req, res });
const isLoginPage = ["/sign-in", "/sign-up"].includes(reqUrl.pathname);
const { data: { session } } = await supabase.auth.getSession();
if (isLoginPage && session) {
return NextResponse.redirect(reqUrl.host);
} else if (!session && !isLoginPage) {
return NextResponse.redirect(`http://${reqUrl.host}/login`);
}
return res;
}
export const config = {
matcher: ["/((?!api|images|icons|_next/static|_next/image|favicon.ico).*)"],
};
El propósito principal de este middleware es garantizar la seguridad y la experiencia del usuario al navegar por la aplicación. Además, en la configuración del middleware, se especificarán las rutas donde se omitirá su uso, adaptándose así a las necesidades específicas del proyecto.
Callback
Sigamos con la creación de archivos. Ahora vamos a crear un callback que nos permitirá recibir la respuesta del proveedor que seleccionamos anteriormente. Este archivo estará ubicado en src/app/auth/callback/route.ts
. Este paso es crucial para manejar la respuesta del proveedor de autenticación y realizar las acciones necesarias en función de esa respuesta.
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
import { cookies } from 'next/headers'
import { type NextRequest, NextResponse } from 'next/server'
export const dynamic = 'force-dynamic'
export async function GET (request: NextRequest) {
const requestUrl = new URL(request.url)
const code = requestUrl.searchParams.get('code')
if (code !== null) {
const supabase = createRouteHandlerClient({ cookies })
await supabase.auth.exchangeCodeForSession(code)
}
return NextResponse.redirect(requestUrl.origin)
}
Sign-in
Una vez completado todo lo anterior, procedemos a crear un componente que mostrará un botón para iniciar sesión en la aplicación. Este botón ejecutará la función signInWithProvider
, que se encargará de realizar el inicio de sesión utilizando la cuenta de terceros seleccionada.
"use client";
import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
import { Icons } from "../icons";
import { Button } from "../ui/button";
import { Provider } from "@supabase/supabase-js";
export default function Providerbuttons() {
const supabase = createClientComponentClient();
const signInWithProvider = async (provider: Provider) => {
const { data, error } = await supabase.auth.signInWithOAuth({
provider,
options: {
redirectTo: "http://localhost:3000/auth/callback",
},
});
};
return (
<div className="grid grid-cols-2 gap-6">
<Button variant="outline" onClick={() => signInWithProvider("github")}>
<Icons.gitHub className="mr-2 h-4 w-4" /> Github
</Button>
<Button variant="outline" onClick={() => signInWithProvider("google")}>
<Icons.google className="mr-2 h-4 w-4" /> Google
</Button>
</div>
);
}
la combinación de Next.js y Supabase ofrece una solución completa para implementar sistemas de autenticación en aplicaciones web. Hemos abordado cómo configurar la conexión con Supabase, gestionar credenciales y crear middleware para proteger rutas en Next.js. Además, destacamos la importancia de permitir a los usuarios registrarse con cuentas de terceros y cómo manejar las respuestas de los proveedores de autenticación. Al implementar esta solución, no solo aseguramos la aplicación, sino que también mejoramos la experiencia del usuario. Estos conocimientos permiten construir sistemas de autenticación sólidos y escalables para proyectos web exitosos.
Posted on March 2, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.