Autorización y autenticación en TypeScript: guía completa
En el desarrollo web moderno, la seguridad de la aplicación es un aspecto crítico. TypeScript, como superconjunto de JavaScript, proporciona herramientas potentes para crear sistemas tipados y seguros de autorización y autenticación. En este artículo, analizaremos los conceptos clave, las bibliotecas populares y escribiremos ejemplos prácticos en TypeScript.
Conceptos básicos
Antes de pasar al código, es importante distinguir dos términos:
- Autenticación (Authentication) — verificación de la identidad del usuario (¿quién eres?). Generalmente se realiza mediante usuario/contraseña, tokens o biometría.
- Autorización (Authorization) — determinación de los derechos de acceso (¿qué puedes hacer?). Por ejemplo, acceso al panel de administración solo para el rol "admin".
Bibliotecas populares para TypeScript
En el ecosistema de TypeScript/Node.js existen varias soluciones probadas:
- Passport.js — la biblioteca más popular para estrategias de autenticación (local, JWT, OAuth). Tiene un excelente soporte para TypeScript a través de los tipos
@types/passport. - jsonwebtoken — trabajo con JWT (JSON Web Tokens). Completamente tipada.
- bcrypt — hash de contraseñas. Se usa junto con otras bibliotecas.
- express-session — gestión de sesiones en el servidor.
Ejemplo 1: Autenticación básica con JWT
Veamos la creación de un sistema simple con tokens de acceso. Instale las dependencias:
npm install express jsonwebtoken bcrypt @types/express @types/jsonwebtoken @types/bcryptCreemos un servidor con registro e inicio de sesión:
import express, { Request, Response } from 'express';import jwt from 'jsonwebtoken';import bcrypt from 'bcrypt';
const app = express();app.use(express.json());
const SECRET_KEY = 'your-secret-key';const users: { username: string; passwordHash: string }[] = [];
// Registroapp.post('/register', async (req: Request, res: Response) => { const { username, password } = req.body; const passwordHash = await bcrypt.hash(password, 10); users.push({ username, passwordHash }); res.status(201).json({ message: 'User created' });});
// Inicio de sesiónapp.post('/login', async (req: Request, res: Response) => { const { username, password } = req.body; const user = users.find(u => u.username === username); if (!user) return res.status(401).json({ error: 'Invalid credentials' });
const isValid = await bcrypt.compare(password, user.passwordHash); if (!isValid) return res.status(401).json({ error: 'Invalid credentials' });
const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: '1h' }); res.json({ token });});
// Ruta protegidaapp.get('/protected', (req: Request, res: Response) => { const authHeader = req.headers.authorization; if (!authHeader) return res.status(401).json({ error: 'No token provided' });
const token = authHeader.split(' ')[1]; // Bearer token try { const decoded = jwt.verify(token, SECRET_KEY); res.json({ message: 'Access granted', user: decoded }); } catch { res.status(403).json({ error: 'Invalid token' }); }});
app.listen(3000, () => console.log('Server running on port 3000'));Ejemplo 2: Middleware para autorización con roles
Añadamos un modelo de roles. Creemos un middleware tipado:
interface JwtPayload { username: string; role: 'user' | 'admin';}
// Middleware para verificar autenticaciónfunction authenticate(req: Request, res: Response, next: Function) { const token = req.headers.authorization?.split(' ')[1]; if (!token) return res.status(401).json({ error: 'Unauthorized' });
try { const decoded = jwt.verify(token, SECRET_KEY) as JwtPayload; (req as any).user = También en la biblioteca
Generación de PDF en Swift (iOS/macOS): UIGraphicsPDFRenderer, PDFKit y Core Graphics
Cliente OAuth para TypeScript: autorización a través de GitHub, Google y otros proveedores
Trabajo con imágenes en PHP: guía completa de GD e Imagick
Configuración de aplicaciones Swift (iOS/macOS): bibliotecas y herramientas
Envío de Email en C# (.NET): biblioteca System.Net.Mail