Autenticación y Autorización de Usuarios: Protege tu API con JWT

La seguridad en APIs es esencial para proteger datos sensibles. JSON Web Tokens (JWT) proporciona un mecanismo robusto para autenticar y autorizar usuarios. Este artículo explica cómo implementar JWT en una API REST usando Node.js y Express.

Estructura de JWT

Un JWT consta de tres partes codificadas en Base64: encabezado, carga útil y firma. El encabezado especifica el algoritmo de firma (por ejemplo, HS256), la carga útil contiene cllaims como el ID de usuario y la expiración, y la firma verifica la integridad del token.

Instalación de Dependencias

npm install express jsonwebtoken dotenv

Configuración del Servidor Express

const express = require('express');
const jwt = require('jsonwebtoken');
require('dotenv').config();

const app = express();
app.use(express.json());

const claveSecreta = process.env.JWT_SECRET || 'mi_clave_segura_2024';

Generación de Tokens

Al autenticar un usuario, se crea un token con un tiempo de expiración limitado.

function crearToken(usuarioId, rol) {
    const cargaUtil = {
        sub: usuarioId,
        role: rol,
        iss: 'api-ejemplo',
        exp: Math.floor(Date.now() / 1000) + 3600 // Expira en 1 hora
    };
    return jwt.sign(cargaUtil, claveSecreta, { algorithm: 'HS256' });
}

app.post('/login', (req, res) => {
    const { nombreUsuario, contrasena } = req.body;
    // Validación simulada (en producción, verificar contra base de datos)
    if (nombreUsuario === 'admin' && contrasena === '1234') {
        const tokenJWT = crearToken('101', 'administrador');
        res.json({ token: tokenJWT });
    } else {
        res.status(401).json({ error: 'Credenciales inválidas' });
    }
});

Middleware de Verificación

Se crea un middleware para proteger rutas, verificando el token en el encabezado Authoriztaion.

function verificarAutenticacion(req, res, proximo) {
    const encabezadoAuth = req.headers.authorization;
    if (!encabezadoAuth || !encabezadoAuth.startsWith('Bearer ')) {
        return res.status(403).json({ error: 'Token no proporcionado' });
    }
    const tokenExtraido = encabezadoAuth.split(' ')[1];
    try {
        const payloadVerificado = jwt.verify(tokenExtraido, claveSecreta, { algorithms: ['HS256'] });
        req.usuario = payloadVerificado;
        proximo();
    } catch (error) {
        res.status(401).json({ error: 'Token inválido o expirado' });
    }
}

app.get('/perfil', verificarAutenticacion, (req, res) => {
    res.json({ mensaje: `Bienvenido, usuario ${req.usuario.sub}` });
});

Autorización Basada en Roles

Se puede extender el middleware para verificar roles específicos.

function verificarRol(rolPermitido) {
    return (req, res, proximo) => {
        if (req.usuario.role !== rolPermitido) {
            return res.status(403).json({ error: 'Acceso denegado' });
        }
        proximo();
    };
}

app.delete('/usuarios/:id', verificarAutenticacion, verificarRol('administrador'), (req, res) => {
    res.json({ mensaje: `Usuario ${req.params.id} eliminado por ${req.usuario.sub}` });
});

Pruebas y Seguridad

Para probar, envíe una solicitud POST a /login con credenciales válidas, luego use el token obtenido en el encabezado Authorization de rutas protegidas.

// Ejemplo de solicitud con curl
// curl -X POST http://localhost:3000/login -H "Content-Type: application/json" -d '{"nombreUsuario":"admin","contrasena":"1234"}'
// curl -H "Authorization: Bearer <token>" http://localhost:3000/perfil</token>

Prácticas recomendadas: usar HTTPS, almacenar claves secretas en variables de entorno, implementar rotación de claves y limitar la duración del token.

Etiquetas: JWT Node.js express API Security Authentication

Publicado el 6-16 03:21