Configurando NextAuth en Next.js 13.4. Parte 2 - Adaptadores
En este articulo explicaré breve y didácticamente como usar los adaptadores de NextAuth para registrar usuarios con Prisma y Planetscale
Contexto
En esta entrega, aprendemos a como hacer para configurar Adapters en Nextauth y para ello utilizaremos Prisma con una base de datos mySQL en Planetscale.
Me gustaría aclarar que si no han usado Prisma hasta ahora, no se preocupen, su sintaxis es bastante amigable a la lectura y creo que este articulo podría ser un incluso un punto de entrada para comenzar a aprenderlos.
Se preguntarán, ¿para que adapters? el fin de configurar los Adapters en el contexto de una App Next.js 13 con NextAuth radica en lo siguiente: digamos un usuario está intentando autenticarse en nuestro sitio mediante un servicio como Google, por ejemplo, y ese usuario no se encuentra actualmente registrado, entonces nuestro Adapter entra en acción y hará el trabajo por nosotros registrando a este nuevo usuario, en nuestra base de datos como por arte de magia (aunque veremos que mientras hacemos las configuraciones necesarias, logramos entender relativamente lo que pasa por detrás de NextAuth para que este register sea posible).
Suena genial y algo complejo, pero hay que recordar que siempre desde el codigo es mas sencillo, así que ¡vamos a darle!
Next Auth
En caso de requerir un repaso sobre que es Next Auth y como lograr hacer un login en pocos pasos, en mi anterior articulo hice una breve intro sobre como configurarlo.
Prisma
Prisma es un ORM creado para Node.js y Typescript que sirve para escribir en Prisma Schema Language, que vendría a ser el lenguaje de esquemas que usa Prisma y nos ahorra escribir consultas SQL de plano. Prisma nos ofrece la facilidad mediante pocos comandos y configuraciones de crear una base de datos y en pocos minutos tenerla funcionando.
En el ejemplo veremos como registrar un usuario y para ello tendremos que tener una base de datos. Aquí es donde Planetscale entra en escena, un servicio que actualmente tiene mucha popularidad y que nos permitirá crear nuestra base de datos mySQL muy facil.
Teniendo esto en claro ya podemos empezar:
Comencemos!
Paso 1. Instalación del entorno:
Lo primero que haremos es hacer git clone
al repositorio donde se encuentra el codigo del anterior blog: Code y una vez clonado hacer npm i
o yarn
, para instalar los paquetes de la app.
Ahora ya tenemos las configuraciones básicas para usar nextAuth y hacer una autenticación, y también algunos components que nos servirán para hacer el login
y logout
.
Importante: Recuerden cambiar el nombre del archivo .env.example por .env y buscar en google console las credenciales para su proyecto.
Paso 2. Instalar y configurar prisma
Para instalar prisma en la terminal ejecutamos
terminal
yarnadd @prisma/client @auth/prisma-adapter
yarnadd prisma --dev
Ahora crearemos en root (en /) la carpeta prisma y dentro el archivo schema.prisma.
Dentro de schema.prisma escribimos:
schema.prisma
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma"
}
generator client {
provider = "prisma-client-js"
}
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}
Ahora debemos actualizar nuestro archivo .env y agregar la siguiente variable de entorno:
DATABASE_URL=
Genial! Ya tenemos la mitad del trabajo hecho, ahora nos falta conectarnos con nuestro base de datos.
Paso 3. Planetscale:
Necesitamos configurar y inicializar nuestra base de datos, para ellos, utilizaremos Planetscale y crearemos una base de datos de tipo SQL.
Para ello, vamos a ir al sitio oficial de Planetscale https://planetscale.com/ y crearemos una cuenta en caso de no tenerla, y una vez dentro del dashboard elegiremos la opcion create new database .
Elegimos la opcion Hobby que es gratis y pedirá que ingresemos una tarjeta de debito o credito (esto es obligatorio y no tiene costo, es gratis, pero igualmente tenemos que ceder este dato).
Por último elegimos create database.
La proxima pantalla nos permite elegir el framework o languaje, elegiremos Prisma y luego damos click a create new password y copiamos la contraseña que se genera en la proxima sección.
El proximo paso es Configure your Prisma application, y nos da a elegir dos opciones Direct o Optimized, elegimos Direct.
Luego se nos ofrece el dato que necesitamos colocar en nuestra variable de entorno DATABASE_URL, por lo tanto copiamos eso y lo pegamos en nuestro archivo .env
.
Con esto hecho, ya tenemos configurada nuestra base de datos y lista para ser usada, pueden apretar en Go to your database overview
y eso los llevará a un dashboard.
Paso 4. Conectando Prisma con Planetscale:
Ahora ya tenemos la base de datos y nuestro archivo schema.prisma,
y necesitamos que ambos se comuniquen entre sí para llenar la base de datos con las tablas que contendrán los usuarios registrados.
Por lo tanto, en una terminal que apunte a nuestro proyecto, vamos a ejecutar:
terminal
npx prisma db push
Podemos comprobar si las tablas fueron creadas si así lo desean haciendo lo siguiente:
Desde Settings vamos a activar la terminal que Planetscale nos ofrece, le damos check a Allow web console access to production branches
Ahora desde console nos conectamos a la terminal
Desde la consola ejecutamos las consultas SQL que necesitamos para comprobar que todo este como queremos:
Genial, ¿no? ya ahora nos falta comprobar que nuestro Back se comunique con nuestro Front y así poder guardar los datos que requerimos, veamos eso en el siguiente paso.
Paso 5. PrismaAdapter:
Ya tenemos el backend en Prisma y la base de datos en Planetscale, ahora necesitamos que el front se comunique con estas dos tecnologias, para ello utilizaremos PrismaAdapter de la libreria auth y también tenemos que hacer algunos agregados y pequeños ajustes a nuestro archivo [...nextauth].ts
Lo primero que haremos es crear dentro de la carpeta src, una carpeta con el nombre lib y dentro debemos crear un archivo con el nombre db.ts, en el cual escribiremos el siguiente codigo:
/src/lib/db.ts
import { PrismaClient } from "@prisma/client";
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const prisma = globalForPrisma.prisma ?? new PrismaClient();
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
Este codigo va a permitirle a NextAuth conectarse con Prisma y con la base de datos.
Luego actualizamos el archivo [...nextauth].ts
[...nextauth].ts
import { prisma } from "@/lib/db";
import { PrismaAdapter } from "@auth/prisma-adapter";
import NextAuth from "next-auth";
import { AuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";
export const authOptions = {
adapter: PrismaAdapter(prisma),
providers: [
GoogleProvider({
clientId: String(process.env.GOOGLE_CLIENT_ID)!,
clientSecret: String(process.env.GOOGLE_CLIENT_SECRET)!
})
],
theme: {
colorScheme: "dark",
logo: "/logo.svg"
},
secret: String(process.env.NEXTAUTH_SECRET)
} as AuthOptions;
export default NextAuth(authOptions);
Paso 6. Comprobando:
Ya podemos comprobar la configuracion hecha, si intentamos hacer un login desde http://localhost:3000/api/auth/signin , nos debería redirigir a http://localhost:3000/ y si vemos en nuestra base de datos, la tabla User mediante una consulta SQL, podemos ver que ya tenemos el registro del nuevo usuario:
Y con esto terminamos la sección de Prisma/Planetscale. Espero que les haya gustado.