Introducción

La autenticación JWT (JSON Web Token) es una técnica popular para autenticar y autorizar usuarios en aplicaciones web. JWT es un estándar abierto (RFC 7519) que define una forma compacta y autónoma de transmitir información de manera segura entre las partes como un objeto JSON. Esta información puede ser verificada y confiada porque está firmada digitalmente.

¿Por qué usar JWT?

  • Compacto: Los tokens JWT son compactos y pueden ser enviados a través de URL, parámetros POST o en un encabezado HTTP.
  • Autónomo: El token contiene toda la información necesaria sobre el usuario, eliminando la necesidad de almacenar sesiones en el servidor.
  • Seguro: Los tokens pueden ser firmados usando un secreto (con el algoritmo HMAC) o un par de claves pública/privada (con RSA o ECDSA).

Estructura de un JWT

Un JWT consta de tres partes separadas por puntos (.):

  1. Header (Encabezado): Contiene el tipo de token (JWT) y el algoritmo de firma.
  2. Payload (Carga útil): Contiene las declaraciones (claims). Estas pueden ser declaraciones registradas, públicas y privadas.
  3. Signature (Firma): Se utiliza para verificar que el mensaje no ha sido alterado.

Ejemplo de un JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
  • Header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  • Payload: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
  • Signature: SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Implementación de JWT en Node.js

Instalación de Dependencias

Para implementar JWT en una aplicación Node.js, utilizaremos el paquete jsonwebtoken. También necesitaremos express para crear nuestro servidor y body-parser para manejar las solicitudes POST.

npm install express body-parser jsonwebtoken

Configuración del Servidor

Primero, configuraremos un servidor básico con Express.

const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');

const app = express();
const PORT = 3000;

app.use(bodyParser.json());

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

Creación de un Endpoint para Autenticación

Vamos a crear un endpoint /login que generará un token JWT cuando un usuario se autentique correctamente.

const users = [
  { id: 1, username: 'user1', password: 'password1' },
  { id: 2, username: 'user2', password: 'password2' }
];

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username && u.password === password);

  if (user) {
    const token = jwt.sign({ id: user.id, username: user.username }, 'your_jwt_secret', { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).json({ message: 'Invalid credentials' });
  }
});

Middleware de Autenticación

Para proteger rutas específicas, crearemos un middleware que verificará el token JWT.

const authenticateJWT = (req, res, next) => {
  const token = req.header('Authorization');

  if (token) {
    jwt.verify(token, 'your_jwt_secret', (err, user) => {
      if (err) {
        return res.sendStatus(403);
      }
      req.user = user;
      next();
    });
  } else {
    res.sendStatus(401);
  }
};

Rutas Protegidas

Ahora podemos proteger nuestras rutas utilizando el middleware authenticateJWT.

app.get('/protected', authenticateJWT, (req, res) => {
  res.json({ message: 'This is a protected route', user: req.user });
});

Ejercicio Práctico

Ejercicio

  1. Objetivo: Implementar un sistema de autenticación JWT en una aplicación Node.js.
  2. Tareas:
    • Crear un servidor Express.
    • Implementar un endpoint /login que genere un token JWT.
    • Crear un middleware de autenticación JWT.
    • Proteger una ruta /protected utilizando el middleware de autenticación.

Solución

const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');

const app = express();
const PORT = 3000;

app.use(bodyParser.json());

const users = [
  { id: 1, username: 'user1', password: 'password1' },
  { id: 2, username: 'user2', password: 'password2' }
];

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username && u.password === password);

  if (user) {
    const token = jwt.sign({ id: user.id, username: user.username }, 'your_jwt_secret', { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).json({ message: 'Invalid credentials' });
  }
});

const authenticateJWT = (req, res, next) => {
  const token = req.header('Authorization');

  if (token) {
    jwt.verify(token, 'your_jwt_secret', (err, user) => {
      if (err) {
        return res.sendStatus(403);
      }
      req.user = user;
      next();
    });
  } else {
    res.sendStatus(401);
  }
};

app.get('/protected', authenticateJWT, (req, res) => {
  res.json({ message: 'This is a protected route', user: req.user });
});

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

Conclusión

En esta sección, hemos aprendido cómo implementar la autenticación JWT en una aplicación Node.js. Hemos cubierto la estructura de un JWT, cómo generar un token, cómo crear un middleware de autenticación y cómo proteger rutas específicas. La autenticación JWT es una técnica poderosa y eficiente para manejar la autenticación y autorización en aplicaciones modernas.

Curso de Node.js

Módulo 1: Introducción a Node.js

Módulo 2: Conceptos Básicos

Módulo 3: Sistema de Archivos y E/S

Módulo 4: HTTP y Servidores Web

Módulo 5: NPM y Gestión de Paquetes

Módulo 6: Framework Express.js

Módulo 7: Bases de Datos y ORMs

Módulo 8: Autenticación y Autorización

Módulo 9: Pruebas y Depuración

Módulo 10: Temas Avanzados

Módulo 11: Despliegue y DevOps

Módulo 12: Proyectos del Mundo Real

© Copyright 2024. Todos los derechos reservados