Autorización OAuth 2.0 y JWT en TypeScript: Guía Completa
Las aplicaciones web modernas y las API requieren mecanismos confiables de autenticación y autorización. Los dos estándares más populares — OAuth 2.0 y JWT (JSON Web Tokens) — se utilizan a menudo juntos para crear sistemas seguros y escalables. En este artículo, exploraremos cómo implementar la autorización OAuth 2.0 y JWT en TypeScript usando Express.js y librerías populares.
¿Qué son OAuth 2.0 y JWT?
OAuth 2.0 es un protocolo de autorización que permite a las aplicaciones obtener acceso limitado a los recursos del usuario sin compartir sus credenciales. Se utiliza ampliamente para el inicio de sesión social (Google, GitHub, Facebook).
JWT (JSON Web Token) es un token compacto y autocontenido que contiene información del usuario y puede verificarse sin consultar una base de datos. JWT se utiliza a menudo como formato para los tokens de acceso en OAuth 2.0.
Juntos, forman un mecanismo potente: OAuth 2.0 gestiona el proceso de emisión de tokens, mientras que JWT garantiza la transmisión y verificación seguras.
Configuración del Proyecto e Instalación de Dependencias
Vamos a crear un nuevo proyecto TypeScript. Asegúrate de tener Node.js instalado (versión 18+).
mkdir oauth-jwt-typescriptcd oauth-jwt-typescriptnpm init -yInstala las dependencias necesarias:
npm install express jsonwebtoken passport passport-google-oauth20 dotenv bcryptjsnpm install -D typescript @types/express @types/jsonwebtoken @types/passport @types/passport-google-oauth20 @types/bcryptjs ts-node nodemonCrea el archivo tsconfig.json:
{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "outDir": "./dist" }, "include": ["src/**/*"]}Estructura del proyecto:
src/ ├── config/ │ └── passport.ts ├── controllers/ │ └── authController.ts ├── middleware/ │ └── authMiddleware.ts ├── models/ │ └── user.ts ├── routes/ │ └── authRoutes.ts ├── services/ │ └── jwtService.ts └── app.tsImplementación de Autorización JWT
Los tokens JWT constan de tres partes: encabezado, payload y firma. Veamos una implementación básica en TypeScript.
Crea un servicio para trabajar con JWT (src/services/jwtService.ts):
import jwt from 'jsonwebtoken';import dotenv from 'dotenv';
dotenv.config();
const ACCESS_SECRET = process.env.JWT_ACCESS_SECRET || 'access-secret-key';const REFRESH_SECRET = process.env.JWT_REFRESH_SECRET || 'refresh-secret-key';
export interface TokenPayload { userId: string; email: string; role: string;}
export const generateAccessToken = (payload: TokenPayload): string => { return jwt.sign(payload, ACCESS_SECRET, { expiresIn: '15m' });};
export const generateRefreshToken = (payload: TokenPayload): string => { return jwt.sign(payload, REFRESH_SECRET, { expiresIn: '7d' });};
export const verifyAccessToken = (token: string): TokenPayload => { return jwt.verify(token, ACCESS_SECRET) as TokenPayload;};
export const verifyRefreshToken = (token: string): TokenPayload => { return jwt.verify(token, REFRESH_SECRET) as TokenPayload;};Crea middleware para la verificación JWT (src/middleware/authMiddleware.ts):
import { Request, Response, NextFunction } from 'express';import { verifyAccessToken } from '../services/jwtService';
export interface AuthRequest extends Request { user?: { userId: string; email: string; role: string; };}
export const authenticateJWT = (req: AuthRequest, res: Response, next: NextFunction): void => { const authHea