Sesiones y Autenticación
La autenticación es un requisito extremadamente común en las aplicaciones web. Esta receta te mostrará cómo implementar un registro de usuario básico y autenticación en tu aplicación Nuxt.
Introducción
En esta receta configuraremos la autenticación en una aplicación Nuxt de pila completa utilizando Nuxt Auth Utils, que proporciona utilidades convenientes para gestionar datos de sesión del lado del cliente y del servidor.
El módulo utiliza cookies seguras y selladas para almacenar datos de sesión, por lo que no necesitas configurar una base de datos para almacenar datos de sesión.
Instalar nuxt-auth-utils
Instala el módulo nuxt-auth-utils
usando el CLI de nuxt
.
npx nuxt module add auth-utils
Este comando instalará nuxt-auth-utils
como dependencia y lo añadirá en la sección modules
de nuestro nuxt.config.ts
Clave de Encriptación de Cookies
Como nuxt-auth-utils
utiliza cookies selladas para almacenar datos de sesión, las cookies de sesión se encriptan usando una clave secreta del entorno NUXT_SESSION_PASSWORD
.
Si no se establece, esta variable de entorno se añadirá automáticamente a tu .env
cuando se ejecute en modo de desarrollo.
NUXT_SESSION_PASSWORD=a-random-password-with-at-least-32-characters
Necesitarás añadir esta variable de entorno a tu entorno de producción antes de desplegar.
Ruta de API de Inicio de Sesión
Para esta receta, crearemos una ruta de API simple para iniciar sesión un usuario basado en datos estáticos.
Vamos a crear una ruta de API /api/login
que aceptará una solicitud POST con el correo electrónico y la contraseña en el cuerpo de la solicitud.
import { z } from 'zod'
const bodySchema = z.object({
email: z.string().email(),
password: z.string().min(8)
})
export default defineEventHandler(async (event) => {
const { email, password } = await readValidatedBody(event, bodySchema.parse)
if (email === 'admin@admin.com' && password === 'iamtheadmin') {
// establece la sesión del usuario en la cookie
// este utilitario del servidor es auto-importado por el módulo auth-utils
await setUserSession(event, {
user: {
name: 'John Doe'
}
})
return {}
}
throw createError({
statusCode: 401,
message: 'Credenciales incorrectas'
})
})
Asegúrate de instalar la dependencia zod
en tu proyecto (npm i zod
).
Lee más sobre el helper del servidor setUserSession
expuesto por nuxt-auth-utils
.
Página de Inicio de Sesión
El módulo expone un composable de Vue para saber si un usuario está autenticado en nuestra aplicación:
const { loggedIn, session, user, clear, fetch } = useUserSession()
Vamos a crear una página de inicio de sesión con un formulario para enviar los datos de inicio de sesión a nuestra ruta /api/login
.
<script setup lang="ts">
const { loggedIn, user, fetch: refreshSession } = useUserSession()
const credentials = reactive({
email: '',
password: '',
})
async function login() {
$fetch('/api/login', {
method: 'POST',
body: credentials
})
.then(async () => {
// Refresca la sesión en el lado del cliente y redirige a la página de inicio
await refreshSession()
await navigateTo('/')
})
.catch(() => alert('Credenciales incorrectas'))
}
</script>
<template>
<form @submit.prevent="login">
<input v-model="credentials.email" type="email" placeholder="Email" />
<input v-model="credentials.password" type="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
</template>
Proteger Rutas de API
Proteger las rutas del servidor es clave para asegurar que tus datos estén seguros. El middleware del lado del cliente es útil para el usuario, pero sin protección del lado del servidor, tus datos aún pueden ser accedidos. Es crítico proteger cualquier ruta con datos sensibles, deberíamos devolver un error 401 si el usuario no ha iniciado sesión en esas.
El módulo auth-utils
proporciona la función utilitaria requireUserSession
para ayudar a asegurar que los usuarios hayan iniciado sesión y tengan una sesión activa.
Vamos a crear un ejemplo de una ruta /api/user/stats
que solo los usuarios autenticados pueden acceder.
export default defineEventHandler(async (event) => {
// asegúrate de que el usuario haya iniciado sesión
// Esto lanzará un error 401 si la solicitud no proviene de una sesión de usuario válida
const { user } = await requireUserSession(event)
// TODO: Obtener algunas estadísticas basadas en el usuario
return {}
});
Proteger Rutas de la Aplicación
Nuestros datos están seguros con la ruta del lado del servidor en su lugar, pero sin hacer nada más, los usuarios no autenticados probablemente obtendrían algunos datos extraños al intentar acceder a la página /users
. Deberíamos crear un middleware del lado del cliente para proteger la ruta en el lado del cliente y redirigir a los usuarios a la página de inicio de sesión.
nuxt-auth-utils
proporciona un conveniente composable useUserSession
que utilizaremos para verificar si el usuario ha iniciado sesión y redirigirlo si no lo está.
Crearemos un middleware en el directorio /middleware
. A diferencia del servidor, el middleware del lado del cliente no se aplica automáticamente a todos los endpoints, y necesitaremos especificar dónde queremos que se aplique.
export default defineNuxtRouteMiddleware(() => {
const { loggedIn } = useUserSession()
// redirige al usuario a la pantalla de inicio de sesión si no está autenticado
if (!loggedIn.value) {
return navigateTo('/login')
}
})
Página de Inicio
Ahora que tenemos nuestro middleware de la aplicación para proteger nuestras rutas, podemos usarlo en nuestra página de inicio que muestra la información de nuestro usuario autenticado. Si el usuario no está autenticado, será redirigido a la página de inicio de sesión.
Usaremos definePageMeta
para aplicar el middleware a la ruta que queremos proteger.
<script setup lang="ts">
definePageMeta({
middleware: ['authenticated'],
})
const { user, clear: clearSession } = useUserSession()
async function logout() {
await clearSession()
await navigateTo('/login')
}
</script>
<template>
<div>
<h1>Bienvenido {{ user.name }}</h1>
<button @click="logout">Cerrar sesión</button>
</div>
</template>
También añadimos un botón de cierre de sesión para limpiar la sesión y redirigir al usuario a la página de inicio de sesión.
Conclusión
Hemos configurado con éxito una autenticación de usuario muy básica y gestión de sesiones en nuestra aplicación Nuxt. También hemos protegido rutas sensibles en el servidor y el lado del cliente para asegurar que solo los usuarios autenticados puedan acceder a ellas.
Como próximos pasos, puedes:
- Añadir autenticación usando los más de 20 proveedores de OAuth soportados
- Añadir una base de datos para almacenar usuarios, ver Nitro SQL Database o NuxtHub SQL Database
- Permitir que los usuarios se registren con correo electrónico y contraseña usando hashing de contraseñas
- Añadir soporte para WebAuthn / Passkeys
Consulta el repositorio de código abierto atidone para un ejemplo completo de una aplicación Nuxt con autenticación OAuth, base de datos y operaciones CRUD.
※Esta página es una traducción no oficial de la documentación oficial de Nuxt.js.
La página correspondiente en la documentación oficial está aquí:
https://nuxt.com/docs/3.x/guide/recipes/sessions-and-authentication