Cómo implementar autenticación en Next.js
Comprender la autenticación es crucial para proteger los datos de tu aplicación. Esta página te guiará a través de las características de React y Next.js que puedes utilizar para implementar autenticación.
Antes de comenzar, es útil dividir el proceso en tres conceptos:
- Autenticación: Verifica si el usuario es quien dice ser. Requiere que el usuario demuestre su identidad con algo que posee, como un nombre de usuario y contraseña.
- Gestión de sesiones: Rastrea el estado de autenticación del usuario entre solicitudes.
- Autorización: Decide qué rutas y datos puede acceder el usuario.
Este diagrama muestra el flujo de autenticación utilizando características de React y Next.js:

Los ejemplos en esta página explican una autenticación básica con nombre de usuario y contraseña con fines educativos. Aunque puedes implementar una solución de autenticación personalizada, para mayor seguridad y simplicidad, recomendamos usar una biblioteca de autenticación. Estas ofrecen soluciones incorporadas para autenticación, gestión de sesiones y autorización, así como características adicionales como inicios de sesión sociales, autenticación multifactor y control de acceso basado en roles. Puedes encontrar una lista en la sección Bibliotecas de Autenticación.
Autenticación
Funcionalidad de registro e inicio de sesión
Puedes usar el elemento <form>
con Server Actions de React y useActionState
para capturar credenciales de usuario, validar campos del formulario y llamar a la API o base de datos de tu Proveedor de Autenticación.
Dado que las Server Actions siempre se ejecutan en el servidor, proporcionan un entorno seguro para manejar la lógica de autenticación.
Aquí están los pasos para implementar la funcionalidad de registro/inicio de sesión:
1. Capturar credenciales del usuario
Para capturar credenciales del usuario, crea un formulario que invoque una Server Action al enviarse. Por ejemplo, un formulario de registro que acepte el nombre, correo electrónico y contraseña del usuario:
2. Validar campos del formulario en el servidor
Usa la Server Action para validar los campos del formulario en el servidor. Si tu proveedor de autenticación no proporciona validación de formularios, puedes usar una biblioteca de validación de esquemas como Zod o Yup.
Usando Zod como ejemplo, puedes definir un esquema de formulario con mensajes de error apropiados:
Para evitar llamadas innecesarias a la API o base de datos de tu proveedor de autenticación, puedes hacer un return
anticipado en la Server Action si algún campo del formulario no coincide con el esquema definido.
De vuelta en tu <SignupForm />
, puedes usar el hook useActionState
de React para mostrar errores de validación mientras se envía el formulario:
Nota importante:
- En React 19,
useFormStatus
incluye claves adicionales en el objeto devuelto, como data, method y action. Si no estás usando React 19, solo está disponible la clavepending
.- Antes de mutar datos, siempre debes asegurarte de que un usuario también esté autorizado para realizar la acción. Consulta Autenticación y Autorización.
3. Crear un usuario o verificar credenciales
Después de validar los campos del formulario, puedes crear una nueva cuenta de usuario o verificar si el usuario existe llamando a la API o base de datos de tu proveedor de autenticación.
Continuando con el ejemplo anterior:
Después de crear exitosamente la cuenta de usuario o verificar las credenciales, puedes crear una sesión para gestionar el estado de autenticación del usuario. Dependiendo de tu estrategia de gestión de sesiones, esta puede almacenarse en una cookie, base de datos o ambas. Continúa en la sección de Gestión de Sesiones para aprender más.
Consejos:
- El ejemplo anterior es detallado ya que desglosa los pasos de autenticación con fines educativos. Esto resalta que implementar tu propia solución segura puede volverse complejo rápidamente. Considera usar una Biblioteca de Autenticación para simplificar el proceso.
- Para mejorar la experiencia del usuario, podrías verificar correos electrónicos o nombres de usuario duplicados antes en el flujo de registro. Por ejemplo, mientras el usuario escribe un nombre de usuario o cuando el campo de entrada pierde el foco. Esto puede evitar envíos innecesarios del formulario y proporcionar retroalimentación inmediata al usuario. Puedes controlar la frecuencia de estas verificaciones con bibliotecas como use-debounce.
Gestión de Sesiones
La gestión de sesiones asegura que el estado autenticado del usuario se mantenga entre solicitudes. Incluye crear, almacenar, actualizar y eliminar sesiones o tokens.
Existen dos tipos de sesiones:
- Sin estado (Stateless): Los datos de la sesión (o un token) se almacenan en las cookies del navegador. La cookie se envía con cada solicitud, permitiendo verificar la sesión en el servidor. Este método es más simple, pero puede ser menos seguro si no se implementa correctamente.
- Base de datos: Los datos de la sesión se almacenan en una base de datos, y el navegador del usuario solo recibe el ID de sesión encriptado. Este método es más seguro, pero puede ser complejo y consumir más recursos del servidor.
Es bueno saber: Aunque puedes usar cualquiera de los métodos, o ambos, recomendamos usar una biblioteca de gestión de sesiones como iron-session o Jose.
Sesiones sin estado (Stateless)
Para crear y gestionar sesiones sin estado, hay algunos pasos que debes seguir:
- Generar una clave secreta, que se usará para firmar tu sesión, y almacenarla como una variable de entorno.
- Escribir lógica para encriptar/desencriptar datos de sesión usando una biblioteca de gestión de sesiones.
- Gestionar cookies usando la API
cookies
de Next.js.
Además de lo anterior, considera añadir funcionalidad para actualizar (o refrescar) la sesión cuando el usuario regrese a la aplicación, y eliminar la sesión cuando el usuario cierre sesión.
Es bueno saber: Verifica si tu biblioteca de autenticación incluye gestión de sesiones.
1. Generar una clave secreta
Hay varias formas de generar una clave secreta para firmar tu sesión. Por ejemplo, puedes usar el comando openssl
en tu terminal:
Este comando genera una cadena aleatoria de 32 caracteres que puedes usar como tu clave secreta y almacenar en tu archivo de variables de entorno:
Luego puedes referenciar esta clave en tu lógica de gestión de sesiones:
2. Encriptar y desencriptar sesiones
A continuación, puedes usar tu biblioteca de gestión de sesiones preferida para encriptar y desencriptar sesiones. Continuando con el ejemplo anterior, usaremos Jose (compatible con el Edge Runtime) y el paquete server-only
de React para asegurar que tu lógica de gestión de sesiones solo se ejecute en el servidor.
Consejos:
- El payload debe contener los datos de usuario mínimos y únicos que se usarán en solicitudes posteriores, como el ID del usuario, rol, etc. No debe contener información personal identificable como número de teléfono, dirección de correo electrónico, información de tarjetas de crédito, etc., o datos sensibles como contraseñas.
3. Configurar cookies (opciones recomendadas)
Para almacenar la sesión en una cookie, usa la API cookies
de Next.js. La cookie debe configurarse en el servidor e incluir las opciones recomendadas:
- HttpOnly: Evita que JavaScript del lado del cliente acceda a la cookie.
- Secure: Usa https para enviar la cookie.
- SameSite: Especifica si la cookie puede enviarse con solicitudes entre sitios.
- Max-Age o Expires: Elimina la cookie después de un período determinado.
- Path: Define la ruta URL para la cookie.
Consulta MDN para más información sobre cada una de estas opciones.
De vuelta en tu Acción de Servidor, puedes invocar la función createSession()
y usar la API redirect()
para redirigir al usuario a la página apropiada:
Consejos:
- Las cookies deben configurarse en el servidor para evitar manipulaciones del lado del cliente.
- 🎥 Mira: Aprende más sobre sesiones sin estado y autenticación con Next.js → YouTube (11 minutos).
Actualizar (o refrescar) sesiones
También puedes extender el tiempo de expiración de la sesión. Esto es útil para mantener al usuario conectado después de que acceda nuevamente a la aplicación. Por ejemplo:
Consejo: Verifica si tu biblioteca de autenticación admite tokens de actualización, que pueden usarse para extender la sesión del usuario.
Eliminación de la sesión
Para eliminar la sesión, puede borrar la cookie:
Luego puede reutilizar la función deleteSession()
en su aplicación, por ejemplo, al cerrar sesión:
Sesiones en base de datos
Para crear y administrar sesiones en base de datos, deberá seguir estos pasos:
- Crear una tabla en su base de datos para almacenar sesiones y datos (o verificar si su biblioteca de autenticación maneja esto).
- Implementar funcionalidad para insertar, actualizar y eliminar sesiones.
- Cifrar el ID de sesión antes de almacenarlo en el navegador del usuario, y asegurarse de que la base de datos y la cookie estén sincronizadas (esto es opcional, pero recomendado para verificaciones optimistas de autenticación en Middleware).
Por ejemplo:
Consejos:
- Para un acceso más rápido, puede considerar agregar caché del servidor durante el tiempo de vida de la sesión. También puede mantener los datos de sesión en su base de datos principal y combinar solicitudes de datos para reducir el número de consultas.
- Puede optar por usar sesiones en base de datos para casos de uso más avanzados, como realizar un seguimiento de la última vez que un usuario inició sesión, el número de dispositivos activos o dar a los usuarios la capacidad de cerrar sesión en todos los dispositivos.
Después de implementar la gestión de sesiones, deberá agregar lógica de autorización para controlar lo que los usuarios pueden acceder y hacer dentro de su aplicación. Continúe a la sección Autorización para obtener más información.
Autorización
Una vez que un usuario está autenticado y se crea una sesión, puede implementar autorización para controlar lo que el usuario puede acceder y hacer dentro de su aplicación.
Hay dos tipos principales de verificaciones de autorización:
- Optimistas: Verifican si el usuario está autorizado para acceder a una ruta o realizar una acción usando los datos de sesión almacenados en la cookie. Estas verificaciones son útiles para operaciones rápidas, como mostrar/ocultar elementos de la interfaz de usuario o redirigir usuarios según permisos o roles.
- Seguras: Verifican si el usuario está autorizado para acceder a una ruta o realizar una acción usando los datos de sesión almacenados en la base de datos. Estas verificaciones son más seguras y se usan para operaciones que requieren acceso a datos sensibles o acciones.
Para ambos casos, recomendamos:
- Crear una Capa de Acceso a Datos (DAL) para centralizar su lógica de autorización.
- Usar Objetos de Transferencia de Datos (DTO) para devolver solo los datos necesarios.
- Opcionalmente usar Middleware para realizar verificaciones optimistas.
Verificaciones optimistas con Middleware (Opcional)
Hay algunos casos donde puede querer usar Middleware y redirigir usuarios según permisos:
- Para realizar verificaciones optimistas. Dado que Middleware se ejecuta en cada ruta, es una buena manera de centralizar la lógica de redirección y pre-filtrar usuarios no autorizados.
- Para proteger rutas estáticas que comparten datos entre usuarios (ej. contenido detrás de un muro de pago).
Sin embargo, dado que Middleware se ejecuta en cada ruta, incluyendo rutas precargadas, es importante solo leer la sesión de la cookie (verificaciones optimistas), y evitar verificaciones en la base de datos para prevenir problemas de rendimiento.
Por ejemplo:
Si bien Middleware puede ser útil para verificaciones iniciales, no debería ser su única línea de defensa para proteger sus datos. La mayoría de las verificaciones de seguridad deberían realizarse lo más cerca posible de su fuente de datos, consulte Capa de Acceso a Datos para obtener más información.
Consejos:
- En Middleware, también puede leer cookies usando
req.cookies.get('session').value
.- Middleware usa el Edge Runtime, verifique si su biblioteca de autenticación y gestión de sesiones son compatibles.
- Puede usar la propiedad
matcher
en Middleware para especificar en qué rutas debería ejecutarse Middleware. Aunque, para autenticación, se recomienda que Middleware se ejecute en todas las rutas.
Creación de una Capa de Acceso a Datos (DAL)
Recomendamos crear una DAL para centralizar sus solicitudes de datos y lógica de autorización.
La DAL debe incluir una función que verifique la sesión del usuario mientras interactúa con su aplicación. Como mínimo, la función debería verificar si la sesión es válida, luego redirigir o devolver la información del usuario necesaria para realizar más solicitudes.
Por ejemplo, cree un archivo separado para su DAL que incluya una función verifySession()
. Luego use la API de cache de React para memorizar el valor de retorno de la función durante un pase de renderizado de React:
Luego puede invocar la función verifySession()
en sus solicitudes de datos, Acciones de Servidor, Manejadores de Ruta:
Consejo:
- Una DAL puede usarse para proteger datos obtenidos en tiempo de solicitud. Sin embargo, para rutas estáticas que comparten datos entre usuarios, los datos se obtendrán en tiempo de compilación y no en tiempo de solicitud. Use Middleware para proteger rutas estáticas.
- Para verificaciones seguras, puede verificar si la sesión es válida comparando el ID de sesión con su base de datos. Use la función cache de React para evitar solicitudes duplicadas innecesarias a la base de datos durante un pase de renderizado.
- Puede consolidar solicitudes de datos relacionadas en una clase JavaScript que ejecute
verifySession()
antes de cualquier método.
Uso de Objetos de Transferencia de Datos (DTO)
Al recuperar datos, se recomienda devolver solo la información necesaria que se utilizará en su aplicación, y no objetos completos. Por ejemplo, si está obteniendo datos de usuario, podría devolver solo el ID y el nombre del usuario, en lugar del objeto de usuario completo que podría contener contraseñas, números de teléfono, etc.
Sin embargo, si no tiene control sobre la estructura de datos devuelta, o está trabajando en equipo y desea evitar que se pasen objetos completos al cliente, puede utilizar estrategias como especificar qué campos son seguros para exponer al cliente.
Al centralizar sus solicitudes de datos y la lógica de autorización en una DAL (Capa de Acceso a Datos) y utilizar DTOs, puede asegurarse de que todas las solicitudes de datos sean seguras y consistentes, facilitando el mantenimiento, auditoría y depuración a medida que su aplicación escala.
Es bueno saberlo:
- Hay varias formas de definir un DTO, desde usar
toJSON()
, hasta funciones individuales como en el ejemplo anterior, o clases de JS. Dado que estos son patrones de JavaScript y no una característica de React o Next.js, recomendamos investigar para encontrar el mejor patrón para su aplicación.- Aprenda más sobre las mejores prácticas de seguridad en nuestro artículo sobre Seguridad en Next.js.
Componentes del Servidor
Las verificaciones de autenticación en Componentes del Servidor son útiles para el acceso basado en roles. Por ejemplo, para renderizar componentes condicionalmente según el rol del usuario:
En el ejemplo, usamos la función verifySession()
de nuestra DAL para verificar los roles 'admin', 'user' y no autorizados. Este patrón asegura que cada usuario interactúe solo con los componentes apropiados para su rol.
Diseños y verificaciones de autenticación
Debido al Renderizado Parcial, tenga cuidado al realizar verificaciones en Diseños, ya que estos no se vuelven a renderizar en la navegación, lo que significa que la sesión del usuario no se verificará en cada cambio de ruta.
En su lugar, debe realizar las verificaciones cerca de su fuente de datos o del componente que se renderizará condicionalmente.
Por ejemplo, considere un diseño compartido que obtiene los datos del usuario y muestra la imagen del usuario en una navegación. En lugar de hacer la verificación de autenticación en el diseño, debe obtener los datos del usuario (getUser()
) en el diseño y hacer la verificación de autenticación en su DAL.
Esto garantiza que donde sea que se llame a getUser()
dentro de su aplicación, se realice la verificación de autenticación, y evita que los desarrolladores olviden verificar si el usuario está autorizado para acceder a los datos.
Es bueno saberlo:
- Un patrón común en SPAs es devolver
null
en un diseño o un componente de nivel superior si un usuario no está autorizado. Este patrón no se recomienda ya que las aplicaciones de Next.js tienen múltiples puntos de entrada, lo que no evitará que se acceda a segmentos de ruta anidados y Acciones del Servidor.
Acciones del Servidor
Trate las Acciones del Servidor con las mismas consideraciones de seguridad que los puntos finales de API públicos, y verifique si el usuario está autorizado para realizar una mutación.
En el ejemplo a continuación, verificamos el rol del usuario antes de permitir que la acción continúe:
Manejadores de Ruta
Trate los Manejadores de Ruta con las mismas consideraciones de seguridad que los puntos finales de API públicos, y verifique si el usuario está autorizado para acceder al Manejador de Ruta.
Por ejemplo:
El ejemplo anterior demuestra un Manejador de Ruta con una verificación de seguridad de dos niveles. Primero verifica si hay una sesión activa, y luego verifica si el usuario que inició sesión es un 'admin'.
Proveedores de Contexto
El uso de proveedores de contexto para autenticación funciona debido al entrelazado. Sin embargo, el context
de React no es compatible con los Componentes del Servidor, lo que los hace aplicables solo a Componentes del Cliente.
Esto funciona, pero cualquier Componente del Servidor hijo se renderizará primero en el servidor y no tendrá acceso a los datos de sesión del proveedor de contexto:
Si se necesitan datos de sesión en Componentes del Cliente (por ejemplo, para la obtención de datos del lado del cliente), use la API taintUniqueValue
de React para evitar que los datos sensibles de sesión se expongan al cliente.
Recursos
Ahora que ha aprendido sobre autenticación en Next.js, aquí hay bibliotecas y recursos compatibles con Next.js para ayudarle a implementar autenticación segura y gestión de sesiones:
Bibliotecas de Autenticación
Bibliotecas de Gestión de Sesiones
Lectura Adicional
Para continuar aprendiendo sobre autenticación y seguridad, consulte los siguientes recursos: