Saltar al pie de página
AYUDA DE NODE

next-auth NPM (Cómo funciona para desarrolladores)

La autenticación es crucial para las aplicaciones web modernas, asegurando que los usuarios puedan acceder de manera segura a sus datos y funciones y proporcionando soporte de infraestructura. NextAuth.js es una biblioteca de autenticación poderosa y flexible diseñada para trabajar sin fricciones con Next.js. Este artículo explorará cómo configurar y usar NextAuth.js en un proyecto de Next.js para que pueda proteger los datos del usuario con facilidad. También le mostraremos cómo este npm puede ser incorporado con otras bibliotecas como la biblioteca IronPDF para autenticación sin estado intuitiva para sus proyectos.

¿Qué es NextAuth.js?

NextAuth.js es una biblioteca de autenticación de código abierto para aplicaciones Next.js que proporciona una forma flexible y segura de implementar autenticación en aplicaciones web. Con NextAuth.js, los desarrolladores pueden integrar fácilmente la autenticación en sus proyectos Next.js sin tener que gestionar las complejidades de la autenticación de usuarios y la gestión de sesiones.

El paquete es altamente configurable, permitiendo a los desarrolladores personalizar los flujos de autenticación, asegurar las rutas de API y manejar las sesiones de usuario sin problemas. Con características mejoradas que le permiten crear sus propios procedimientos para gestionar el acceso a cuentas, encriptar y decodificar JSON Web Tokens, y establecer políticas de seguridad de cookies personalizadas y atributos de sesión, lo cual le permite regular el acceso a cuentas y la frecuencia de verificación de sesiones.

¿Por qué elegir NextAuth.js?

NextAuth.js ofrece varios beneficios:

  • Facilidad de Uso: Configuración sencilla con mínima configuración.
  • Flexibilidad: Soporta varios proveedores de autenticación, incluyendo OAuth, email/contraseña y más.
  • Seguridad: Funciones de seguridad integradas para proteger los datos del usuario para su propia base de datos.
  • Extensibilidad: Fácilmente extensible para satisfacer necesidades de autenticación personalizadas.

Cómo empezar con el npm de NextAuth.js

Primero, vamos a crear un nuevo proyecto de Next.js. Abra su terminal y ejecute:

npx create-next-app@latest my-next-auth-app
cd my-next-auth-app
npx create-next-app@latest my-next-auth-app
cd my-next-auth-app
SHELL

A continuación, instale NextAuth.js:

npm install next-auth
npm install next-auth
SHELL

Cómo configurar NextAuth.js

Cree un nuevo archivo para su ruta de API para manejar la autenticación. En el directorio pages/api/auth, cree el siguiente archivo [...nextauth].js:

// pages/api/auth/[...nextauth].js
import NextAuth from 'next-auth';
import GitHubProvider from 'next-auth/providers/github';
import GoogleProvider from 'next-auth/providers/google';

// Configuring NextAuth to use GitHub and Google providers for authentication
export default NextAuth({
  providers: [
    GitHubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET, // Secret for encrypting tokens if needed
});
// pages/api/auth/[...nextauth].js
import NextAuth from 'next-auth';
import GitHubProvider from 'next-auth/providers/github';
import GoogleProvider from 'next-auth/providers/google';

// Configuring NextAuth to use GitHub and Google providers for authentication
export default NextAuth({
  providers: [
    GitHubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET, // Secret for encrypting tokens if needed
});
JAVASCRIPT

Variables de entorno

Cree un archivo .env.local en la raíz de su proyecto para almacenar sus variables de entorno:

# Just make sure to fill out the variables with your actual information!
GITHUB_ID=your_github_client_id
GITHUB_SECRET=your_github_client_secret
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
NEXTAUTH_SECRET=your_nextauth_secret

Añadir autenticación a su aplicación

Ahora, vamos a añadir la autenticación a su aplicación. Cree un botón de inicio de sesión y un componente de perfil para mostrar la información del usuario.

// components/LoginButton.js
import { signIn, signOut, useSession } from 'next-auth/react';

const LoginButton = () => {
  const { data: session, status } = useSession();
  const loading = status === "loading"; // Used to determine loading state
  return (
    <div>
      {!session && ( // Render sign-in buttons when session is not active
        <>
          <button onClick={() => signIn('github')}>Sign in with GitHub</button>
          <button onClick={() => signIn('google')}>Sign in with Google</button>
        </>
      )}
      {session && ( // Display user info and sign-out option when session is active
        <>
          <p>Signed in as {session.user.email}</p>
          <button onClick={() => signOut()}>Sign out</button>
        </>
      )}
    </div>
  );
};

export default LoginButton;
// components/LoginButton.js
import { signIn, signOut, useSession } from 'next-auth/react';

const LoginButton = () => {
  const { data: session, status } = useSession();
  const loading = status === "loading"; // Used to determine loading state
  return (
    <div>
      {!session && ( // Render sign-in buttons when session is not active
        <>
          <button onClick={() => signIn('github')}>Sign in with GitHub</button>
          <button onClick={() => signIn('google')}>Sign in with Google</button>
        </>
      )}
      {session && ( // Display user info and sign-out option when session is active
        <>
          <p>Signed in as {session.user.email}</p>
          <button onClick={() => signOut()}>Sign out</button>
        </>
      )}
    </div>
  );
};

export default LoginButton;
JAVASCRIPT

Explicación del código

El componente LoginButton maneja la autenticación del usuario en una aplicación Next.js usando NextAuth.js. Utiliza el gancho useSession para determinar si un usuario ha iniciado sesión. Si el usuario no está autenticado, muestra botones que les permiten iniciar sesión usando GitHub o Google. Si el usuario está autenticado, muestra un mensaje con su correo electrónico y un botón para cerrar sesión. Este componente proporciona una interfaz simple para manejar las acciones de inicio y cierre de sesión del usuario a través de la manipulación de un objeto de sesión.

Protección de rutas

Para proteger rutas y asegurar que solo los usuarios autenticados puedan acceder a ciertas páginas, use la función getSession de NextAuth.js.

// pages/protected.js
import { getSession } from 'next-auth/react';

const ProtectedPage = ({ session }) => {
  if (!session) {
    return <p>You need to be authenticated to view this page.</p>;
  }
  return <p>Welcome, {session.user.email}!</p>;
};

export async function getServerSideProps(context) {
  const session = await getSession(context); // Fetch session data server-side
  return {
    props: { session },
  };
}

export default ProtectedPage;
// pages/protected.js
import { getSession } from 'next-auth/react';

const ProtectedPage = ({ session }) => {
  if (!session) {
    return <p>You need to be authenticated to view this page.</p>;
  }
  return <p>Welcome, {session.user.email}!</p>;
};

export async function getServerSideProps(context) {
  const session = await getSession(context); // Fetch session data server-side
  return {
    props: { session },
  };
}

export default ProtectedPage;
JAVASCRIPT

Explicación del código

El componente ProtectedPage en una aplicación Next.js usa NextAuth.js para restringir el acceso solo a usuarios autenticados. Recupera las propiedades de la sesión del usuario del lado del servidor usando getServerSideProps y las pasa como una prop al componente. Si el usuario no está autenticado, la página muestra un mensaje indicando que se requiere autenticación. Si el usuario está autenticado, le da la bienvenida mostrando su dirección de correo electrónico. Esta configuración asegura que solo los usuarios con sesión iniciada puedan acceder al contenido de la página.

Presentando IronPDF

IronPDF es una poderosa biblioteca PDF de node.js que permite a los desarrolladores generar y editar PDFs en sus proyectos de node.js. Ya sea que necesite crear PDFs a partir de HTML, manipular PDFs existentes o convertir páginas web a formato PDF, IronPDF lo tiene cubierto.

next-auth NPM (Cómo Funciona Para Desarrolladores): Figura 1 - IronPDF para Node.js: La Biblioteca PDF de Node.js

Características clave

Conversión de HTML a PDF

Convertir contenido HTML en documentos PDF sin esfuerzo. Esta característica es particularmente útil para generar PDFs dinámicos a partir de contenido web.

Conversión de URL a PDF

Generar PDFs directamente desde URLs, lo que le permite capturar el contenido de páginas web y guardarlas como archivos PDF programáticamente.

Manipulación de PDF

Fusionar, dividir y manipular documentos PDF existentes con facilidad. IronPDF proporciona funcionalidades como añadir páginas, dividir documentos y más.

Seguridad en PDF

Proteja sus documentos PDF encriptándolos con contraseñas o aplicando firmas digitales. IronPDF ofrece opciones para proteger sus documentos sensibles contra el acceso no autorizado.

Resultados de alta calidad

Producir documentos PDF de alta calidad con representación precisa de texto, imágenes y formato. IronPDF asegura que sus PDFs generados mantengan la fidelidad al contenido original.

Compatibilidad multiplataforma

IronPDF es compatible con varias plataformas, incluyendo Windows, Linux y macOS, lo que lo hace apto para una amplia gama de entornos de desarrollo.

Integración sencilla

Integre fácilmente IronPDF en sus aplicaciones de Node.js usando su paquete npm. La API está bien documentada, lo que hace que sea sencillo incorporar capacidades de generación de PDF en sus proyectos.

Instalación

Para instalar el paquete IronPDF, use el siguiente comando:

yarn add @ironsoftware/ironpdf @ironsoftware/ironpdf-engine-windows-x64
yarn add @ironsoftware/ironpdf @ironsoftware/ironpdf-engine-windows-x64
SHELL

Generar documentos PDF con IronPDF y NextAuth.js

Instala Dependencias: Primero, crea un nuevo proyecto Next.js (si aún no lo has hecho) usando el siguiente comando:

npx create-next-app@latest nextauth-pdf --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
npx create-next-app@latest nextauth-pdf --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
SHELL

A continuación, navega al directorio de tu proyecto:

cd nextauth
cd nextauth
SHELL

Instale los paquetes requeridos:

yarn add @ironsoftware/ironpdf @ironsoftware/ironpdf-engine-windows-x64
yarn add next-auth
yarn add @ironsoftware/ironpdf @ironsoftware/ironpdf-engine-windows-x64
yarn add next-auth
SHELL

Crear un generador de PDF

API de Generación de PDF: El primer paso es crear una API backend para generar el documento PDF. Dado que IronPDF solo se ejecuta del lado del servidor, necesitamos crear una API para llamar cuando un usuario quiera generar un PDF. Cree un archivo en la ruta pages/api/pdf.js y agregue el siguiente contenido:

// pages/api/pdf.js
import { IronPdf } from "@ironsoftware/ironpdf";
import { format } from 'date-fns'; // Import the format function for date formatting

// Apply your IronPDF license key
IronPdf.GlobalSettings.LicenseKey = "Your license key goes here";

export default async function handler(req, res) {
  try {
    const currentDate = new Date();
    const formattedDate = format(currentDate, 'MMMM do, yyyy');
    // Defining the HTML content for the PDF
    let content = "<h1>Demo React Hook Form and Generate PDF Using IronPDF</h1>";
    content += `<p>Date: ${currentDate}</p>`;
    content += `<p>Formatted Date: ${formattedDate}</p>`;
    // Convert HTML content to PDF
    const pdf = await IronPdf.HtmlToPdfDocument({ htmlContent: content });
    const data = await pdf.toBuffer(); // Convert the PDF to a buffer for response
    res.setHeader("Content-Type", "application/pdf");
    res.setHeader(
      "Content-Disposition",
      "attachment; filename=awesomeIron.pdf"
    );
    res.send(data); // Send the PDF file as a response
  } catch (error) {
    console.error("Error generating PDF:", error);
    res.status(500).end();
  }
}
// pages/api/pdf.js
import { IronPdf } from "@ironsoftware/ironpdf";
import { format } from 'date-fns'; // Import the format function for date formatting

// Apply your IronPDF license key
IronPdf.GlobalSettings.LicenseKey = "Your license key goes here";

export default async function handler(req, res) {
  try {
    const currentDate = new Date();
    const formattedDate = format(currentDate, 'MMMM do, yyyy');
    // Defining the HTML content for the PDF
    let content = "<h1>Demo React Hook Form and Generate PDF Using IronPDF</h1>";
    content += `<p>Date: ${currentDate}</p>`;
    content += `<p>Formatted Date: ${formattedDate}</p>`;
    // Convert HTML content to PDF
    const pdf = await IronPdf.HtmlToPdfDocument({ htmlContent: content });
    const data = await pdf.toBuffer(); // Convert the PDF to a buffer for response
    res.setHeader("Content-Type", "application/pdf");
    res.setHeader(
      "Content-Disposition",
      "attachment; filename=awesomeIron.pdf"
    );
    res.send(data); // Send the PDF file as a response
  } catch (error) {
    console.error("Error generating PDF:", error);
    res.status(500).end();
  }
}
JAVASCRIPT

Esto crea una ruta de API Next.js que genera un archivo PDF usando la biblioteca IronPDF. Crea una cadena HTML que contiene un encabezado y la fecha actual, formatea la fecha utilizando date-fns y convierte el HTML en un PDF. El PDF generado se devuelve como un archivo descargable en la respuesta. Este enfoque permite la generación dinámica de PDFs en un entorno del lado del servidor, siendo útil para crear informes, facturas u otros documentos sobre la marcha.

Ahora añadamos un inicio de sesión GIT en nuestro sitio web frontal usando Next-Auth. Para esto, necesitamos obtener el GitID y la contraseña del usuario. Inicie sesión en Git y vaya a Configuración de desarrollador.

next-auth NPM (Cómo Funciona Para Desarrolladores): Figura 2 - Dónde encontrar la configuración del desarrollador para Git

Haga clic en Nuevo App de GitHub y agregue los detalles de su sitio web:

next-auth NPM (Cómo Funciona Para Desarrolladores): Figura 3 - Agregar detalles del sitio web en GitHub

Almacene el App ID y el Client ID en un lugar seguro. Luego cree un archivo .env.local en la raíz de su proyecto para almacenar sus variables de entorno:

# Here you can use the App and Client ID you just got from GitHub
GITHUB_ID=your_github_client_id
GITHUB_SECRET=your_github_client_secret
NEXTAUTH_SECRET=secret

Cree un nuevo archivo para su ruta de API para manejar la autenticación. En el directorio pages/api/auth, cree un archivo [...nextauth].js así:

// pages/api/auth/[...nextauth].js
import NextAuth from 'next-auth';
import GitHubProvider from 'next-auth/providers/github';

// Setting up NextAuth with GitHub provider
export default NextAuth({
  providers: [
    GitHubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
});
// pages/api/auth/[...nextauth].js
import NextAuth from 'next-auth';
import GitHubProvider from 'next-auth/providers/github';

// Setting up NextAuth with GitHub provider
export default NextAuth({
  providers: [
    GitHubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
});
JAVASCRIPT

Y añada un componente llamado LoginButton.js. Que contendrá lo siguiente:

// components/LoginButton.js
import { useSession, signIn, signOut } from "next-auth/react"

export default function Component() {
  const { data: session } = useSession()
  if (session) { // Display sign-out button and user info when session is active
    return (
      <>
        Signed in as {session.user.email} <br />
        <button onClick={() => signOut()}>Sign out</button>
      </>
    )
  }
  return ( // Display sign-in button when not signed in
    <>
      Not signed in <br />
      <button onClick={() => signIn()}>Sign in</button>
    </>
  )
}
// components/LoginButton.js
import { useSession, signIn, signOut } from "next-auth/react"

export default function Component() {
  const { data: session } = useSession()
  if (session) { // Display sign-out button and user info when session is active
    return (
      <>
        Signed in as {session.user.email} <br />
        <button onClick={() => signOut()}>Sign out</button>
      </>
    )
  }
  return ( // Display sign-in button when not signed in
    <>
      Not signed in <br />
      <button onClick={() => signIn()}>Sign in</button>
    </>
  )
}
JAVASCRIPT

Modifique su index.js como sigue:

// pages/index.js
import Head from "next/head";
import styles from "../styles/Home.module.css";
import React, { useState, useEffect } from "react";
import { format } from "date-fns";
import LoginButton from "../components/LoginButton";
import { useSession } from "next-auth/react";

export default function Home() {
  const [text, setText] = useState("");
  const { data: session } = useSession();

  useEffect(() => {
    const currentDate = new Date();
    const formattedDate = format(currentDate, "MMMM do, yyyy");
    setText(formattedDate); // Set initial text state to formatted current date
  }, []);

  const generatePdf = async () => {
    try {
      const response = await fetch("/api/pdf-datefns?f=" + text);
      const blob = await response.blob();
      const url = window.URL.createObjectURL(new Blob([blob]));
      const link = document.createElement("a");
      link.href = url;
      link.setAttribute("download", "awesomeIron.pdf");
      document.body.appendChild(link);
      link.click();
      link.parentNode.removeChild(link); // Clean up after downloading
    } catch (error) {
      console.error("Error generating PDF:", error);
    }
  };

  const handleChange = (event) => {
    setText(event.target.value); // Update the text state with input value
  };

  return (
    <div className={styles.container}>
      <Head>
        <title>Generate PDF Using IronPDF</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <h1>Demo Next Auth and Generate PDF Using IronPDF</h1>
        {!session && <LoginButton />}
        {session && (
          <>
            <p className="w-full text-center">
              <span className="px-4 text-xl border-gray-500">
                You are logged in enter URL to convert to PDF:
              </span>
              <input
                className="border border-gray-700 w-1/4"
                onChange={handleChange}
                placeholder="Enter URL here..."
              />
            </p>
            <button
              className="rounded-sm bg-blue-800 p-2 m-12 text-xl text-white"
              onClick={generatePdf}
            >
              Generate PDF
            </button>
          </>
        )}
      </main>
      <style jsx>{`
        main {
          padding: 5rem 0;
          flex: 1;
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
        }
        footer {
          width: 100%;
          height: 100px;
          border-top: 1px solid #eaeaea;
          display: flex;
          justify-content: center;
          align-items: center;
        }
        footer img {
          margin-left: 0.5rem;
        }
        footer a {
          display: flex;
          justify-content: center;
          align-items: center;
          text-decoration: none;
          color: inherit;
        }
        code {
          background: #fafafa;
          border-radius: 5px;
          padding: 0.75rem;
          font-size: 1.1rem;
          font-family:
            Menlo,
            Monaco,
            Lucida Console,
            Liberation Mono,
            DejaVu Sans Mono,
            Bitstream Vera Sans Mono,
            Courier New,
            monospace;
        }
      `}</style>
      <style jsx global>{`
        html,
        body {
          padding: 0;
          margin: 0;
          font-family:
            -apple-system,
            BlinkMacSystemFont,
            Segoe UI,
            Roboto,
            Oxygen,
            Ubuntu,
            Cantarell,
            Fira Sans,
            Droid Sans,
            Helvetica Neue,
            sans-serif;
        }
        * {
          box-sizing: border-box;
        }
      `}</style>
    </div>
  );
}
// pages/index.js
import Head from "next/head";
import styles from "../styles/Home.module.css";
import React, { useState, useEffect } from "react";
import { format } from "date-fns";
import LoginButton from "../components/LoginButton";
import { useSession } from "next-auth/react";

export default function Home() {
  const [text, setText] = useState("");
  const { data: session } = useSession();

  useEffect(() => {
    const currentDate = new Date();
    const formattedDate = format(currentDate, "MMMM do, yyyy");
    setText(formattedDate); // Set initial text state to formatted current date
  }, []);

  const generatePdf = async () => {
    try {
      const response = await fetch("/api/pdf-datefns?f=" + text);
      const blob = await response.blob();
      const url = window.URL.createObjectURL(new Blob([blob]));
      const link = document.createElement("a");
      link.href = url;
      link.setAttribute("download", "awesomeIron.pdf");
      document.body.appendChild(link);
      link.click();
      link.parentNode.removeChild(link); // Clean up after downloading
    } catch (error) {
      console.error("Error generating PDF:", error);
    }
  };

  const handleChange = (event) => {
    setText(event.target.value); // Update the text state with input value
  };

  return (
    <div className={styles.container}>
      <Head>
        <title>Generate PDF Using IronPDF</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <h1>Demo Next Auth and Generate PDF Using IronPDF</h1>
        {!session && <LoginButton />}
        {session && (
          <>
            <p className="w-full text-center">
              <span className="px-4 text-xl border-gray-500">
                You are logged in enter URL to convert to PDF:
              </span>
              <input
                className="border border-gray-700 w-1/4"
                onChange={handleChange}
                placeholder="Enter URL here..."
              />
            </p>
            <button
              className="rounded-sm bg-blue-800 p-2 m-12 text-xl text-white"
              onClick={generatePdf}
            >
              Generate PDF
            </button>
          </>
        )}
      </main>
      <style jsx>{`
        main {
          padding: 5rem 0;
          flex: 1;
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
        }
        footer {
          width: 100%;
          height: 100px;
          border-top: 1px solid #eaeaea;
          display: flex;
          justify-content: center;
          align-items: center;
        }
        footer img {
          margin-left: 0.5rem;
        }
        footer a {
          display: flex;
          justify-content: center;
          align-items: center;
          text-decoration: none;
          color: inherit;
        }
        code {
          background: #fafafa;
          border-radius: 5px;
          padding: 0.75rem;
          font-size: 1.1rem;
          font-family:
            Menlo,
            Monaco,
            Lucida Console,
            Liberation Mono,
            DejaVu Sans Mono,
            Bitstream Vera Sans Mono,
            Courier New,
            monospace;
        }
      `}</style>
      <style jsx global>{`
        html,
        body {
          padding: 0;
          margin: 0;
          font-family:
            -apple-system,
            BlinkMacSystemFont,
            Segoe UI,
            Roboto,
            Oxygen,
            Ubuntu,
            Cantarell,
            Fira Sans,
            Droid Sans,
            Helvetica Neue,
            sans-serif;
        }
        * {
          box-sizing: border-box;
        }
      `}</style>
    </div>
  );
}
JAVASCRIPT

Resultado del ejemplo de código

Primera página

next-auth NPM (Cómo Funciona Para Desarrolladores): Figura 4 - Sitio web generado

Página de inicio de sesión

next-auth NPM (Cómo Funciona Para Desarrolladores): Figura 5 - Botón de inicio de sesión con GitHub

Después de iniciar sesión

next-auth NPM (Cómo Funciona Para Desarrolladores): Figura 6 - Página principal de generación de PDF

PDF generado

next-auth NPM (Cómo Funciona Para Desarrolladores): Figura 7 - PDF Generado como Salida

Licencia de IronPDF

IronPDF.

Asegúrese de recordar colocar la clave de licencia que recibe al inicio de su código de esta manera:

// Adjust paths as necessary depending on how you import IronPDF
import { IronPdfGlobalConfig, PdfDocument } from "@ironsoftware/ironpdf";

// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";
// Adjust paths as necessary depending on how you import IronPDF
import { IronPdfGlobalConfig, PdfDocument } from "@ironsoftware/ironpdf";

// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";
JAVASCRIPT

Conclusión

Al final, NextAuth.js simplifica el proceso de añadir autenticación a sus aplicaciones Next.js. Con soporte para múltiples proveedores y características de seguridad robustas, es una excelente opción para manejar la autenticación de usuarios. Siempre puede explorar la documentación de NextAuth.js para configuraciones y características más avanzadas. Además de eso, IronPDF Node.js proporciona capacidades robustas de generación y manipulación de PDFs a su aplicación e integra bien con el desarrollo moderno de aplicaciones.

Darrius Serrant
Ingeniero de Software Full Stack (WebOps)

Darrius Serrant tiene una licenciatura en Ciencias de la Computación de la Universidad de Miami y trabaja como Ingeniero de Marketing WebOps Full Stack en Iron Software. Atraído por la programación desde joven, vio la computación como algo misterioso y accesible, convirtiéndolo en el ...

Leer más