Autorización y autenticación en Node.js: Guía completa
En el desarrollo web moderno, la seguridad de los datos del usuario es la prioridad número uno. En esta guía, analizaremos las herramientas y bibliotecas clave para implementar autenticación (verificación de la identidad del usuario) y autorización (verificación de permisos de acceso) en aplicaciones Node.js. Aprenderás a configurar la protección de rutas, hashear contraseñas y trabajar con tokens de acceso.
1. Conceptos básicos
- Autenticación — proceso de verificar si un usuario es quien dice ser (generalmente mediante usuario y contraseña).
- Autorización — determinación de qué recursos y acciones están disponibles para un usuario autenticado.
- JWT (JSON Web Token) — forma compacta y autónoma de transmitir datos como un objeto JSON. Se utiliza para crear tokens de acceso.
- Sesiones — método tradicional de almacenar datos del usuario en el servidor (generalmente usando
express-session).
2. Bibliotecas clave para Node.js
2.1. bcrypt — hasheo de contraseñas
Nunca almacenes contraseñas en texto plano. bcrypt es una biblioteca para hasheo seguro con sal.
const bcrypt = require('bcrypt');const saltRounds = 10;
// Hasheo de contraseñaasync function hashPassword(password) { const salt = await bcrypt.genSalt(saltRounds); const hash = await bcrypt.hash(password, salt); return hash;}
// Verificación de contraseñaasync function checkPassword(password, hash) { const match = await bcrypt.compare(password, hash); return match; // true o false}2.2. jsonwebtoken — trabajo con JWT
La biblioteca jsonwebtoken permite crear y verificar tokens JWT. Los tokens generalmente constan de encabezado, carga útil (payload) y firma.
const jwt = require('jsonwebtoken');const secretKey = 'tu-clave-secreta';
// Creación de tokenfunction generateToken(userId, role) { const payload = { userId, role }; const token = jwt.sign(payload, secretKey, { expiresIn: '1h' }); return token;}
// Verificación de token (middleware)function verifyToken(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN if (!token) return res.status(401).json({ error: 'Token no proporcionado' });
jwt.verify(token, secretKey, (err, decoded) => { if (err) return res.status(403).json({ error: 'Token inválido' }); req.user = decoded; next(); });}2.3. Passport.js — autenticación universal
Passport.js es un middleware para Express que soporta más de 500 estrategias (local, OAuth, JWT, Google, Facebook, etc.). Ejemplo de estrategia local:
const passport = require('passport');const LocalStrategy = require('passport-local').Strategy;const User = require('./models/User');
passport.use(new LocalStrategy( async (username, password, done) => { try { const user = await User.findOne({ username }); if (!user) return done(null, false, { message: 'Usuario no encontrado' }); const isValid = await bcrypt.compare(password, user.password); if (!isValid) return done(null, false, { message: 'Contraseña incorrecta' }); return done(null, user); } catch (err) { return done(err); } }));
// Serialización y deserialización (para sesiones)passport.serializeUser((user, done) => done(null, user.id));passport.deserializeUser(async (id, done) => { const user = await User.findById(id); done(null, user);});3. Ejemplo completo: registro e inicio de sesión
Unamos todo en una aplicación Express simple.
const express = También en la biblioteca
validator — Validación de datos en Rust
Planificador de tareas en TypeScript: biblioteca node-schedule
Migraciones de bases de datos en Rust: revisión de herramientas Diesel, SeaORM y sqlx
Jakarta Mail (JavaMail) para Java: guía completa con ejemplos