<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Adrian Grahl</title>
    <description>The latest articles on Forem by Adrian Grahl (@adriangrahldev).</description>
    <link>https://forem.com/adriangrahldev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2190319%2F056297d8-99e2-4903-9859-b5f9395b8235.jpeg</url>
      <title>Forem: Adrian Grahl</title>
      <link>https://forem.com/adriangrahldev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/adriangrahldev"/>
    <language>en</language>
    <item>
      <title>Las herramientas imprescindibles para desarrolladores Full Stack en 2024</title>
      <dc:creator>Adrian Grahl</dc:creator>
      <pubDate>Wed, 09 Oct 2024 17:20:08 +0000</pubDate>
      <link>https://forem.com/adriangrahldev/las-herramientas-imprescindibles-para-desarrolladores-full-stack-en-2024-146g</link>
      <guid>https://forem.com/adriangrahldev/las-herramientas-imprescindibles-para-desarrolladores-full-stack-en-2024-146g</guid>
      <description>&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;El desarrollo full stack ha avanzado mucho en los últimos años. Para mantenerse competitivo, es crucial contar con herramientas que faciliten el desarrollo, la gestión de proyectos y la colaboración en equipos. En este artículo, compartiré las herramientas que, según mi experiencia, son esenciales para desarrolladores full stack en 2024, abarcando tecnologías de backend, frontend, bases de datos, pruebas y despliegue.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Lenguajes y Frameworks Backend
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; con &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express.js&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Node.js&lt;/strong&gt; sigue siendo popular para el desarrollo backend gracias a su naturaleza asíncrona y su amplio ecosistema. &lt;strong&gt;Express.js&lt;/strong&gt; es ideal para crear APIs RESTful rápidas y flexibles.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://nestjs.com/" rel="noopener noreferrer"&gt;NestJS&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;NestJS&lt;/strong&gt; se está convirtiendo en el framework preferido para quienes buscan estructura y escalabilidad. Aporta modularidad y hace uso de patrones como la inyección de dependencias, ideal para aplicaciones complejas.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Frameworks Frontend
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://es.react.dev/" rel="noopener noreferrer"&gt;React&lt;/a&gt; y &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;React&lt;/strong&gt; sigue siendo el estándar en desarrollo frontend gracias a su enfoque declarativo y comunidad activa. &lt;strong&gt;Next.js&lt;/strong&gt; ofrece &lt;strong&gt;SSR (Server-Side Rendering)&lt;/strong&gt; y &lt;strong&gt;SSG (Static Site Generation)&lt;/strong&gt;, optimizando el rendimiento y mejorando el SEO.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://svelte.dev/" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt; y &lt;a href="https://kit.svelte.dev/" rel="noopener noreferrer"&gt;SvelteKit&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Svelte&lt;/strong&gt; está ganando popularidad por su enfoque de compilación, generando aplicaciones ligeras y rápidas. &lt;strong&gt;SvelteKit&lt;/strong&gt; ofrece una experiencia de desarrollo sencilla y con alto rendimiento.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Bases de Datos
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.mongodb.com/es" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;MongoDB&lt;/strong&gt; es la base de datos NoSQL más utilizada para aplicaciones modernas, gracias a su flexibilidad y facilidad de uso. &lt;strong&gt;Mongoose&lt;/strong&gt; facilita la gestión de la base de datos desde Node.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt; sigue siendo una de las bases de datos relacionales más apreciadas. Es ideal para proyectos que requieren integridad referencial y transacciones complejas.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Herramientas de Desarrollo y Testing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://code.visualstudio.com" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt; (VSCode)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;VSCode&lt;/strong&gt; sigue siendo el editor preferido por la mayoría de los desarrolladores, gracias a su amplia colección de extensiones como &lt;strong&gt;Prettier&lt;/strong&gt;, &lt;strong&gt;ESLint&lt;/strong&gt; e integraciones con &lt;strong&gt;Git&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://jestjs.io/" rel="noopener noreferrer"&gt;Jest&lt;/a&gt; y &lt;a href="https://www.cypress.io/" rel="noopener noreferrer"&gt;Cypress&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Jest&lt;/strong&gt; es la herramienta predilecta para pruebas unitarias y de integración en aplicaciones JavaScript. &lt;strong&gt;Cypress&lt;/strong&gt; es el estándar para pruebas end-to-end (E2E), ofreciendo una experiencia de prueba intuitiva y visual.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Contenedores y Despliegue
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Docker&lt;/strong&gt; es fundamental para empaquetar y desplegar aplicaciones de manera consistente. Permite crear contenedores ligeros y reproducibles, simplificando el despliegue.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://kubernetes.io/es/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Para gestionar contenedores a gran escala, &lt;strong&gt;Kubernetes&lt;/strong&gt; sigue siendo la solución más popular. Sus capacidades de orquestación y escalabilidad lo hacen esencial para aplicaciones que necesitan alta disponibilidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Automatización y CI/CD
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt; es una excelente opción para automatizar flujos de trabajo, especialmente para quienes usan GitHub. Permite definir pipelines de &lt;strong&gt;CI/CD&lt;/strong&gt; directamente en el repositorio, integrando pruebas y despliegues automáticos.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.jenkins.io/" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Jenkins&lt;/strong&gt; sigue siendo una herramienta poderosa para la automatización de procesos de desarrollo. Es comúnmente usada en proyectos grandes para automatizar pruebas y despliegues, integrando múltiples servicios y herramientas.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Servicios en la Nube
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;AWS &lt;/a&gt;y &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AWS&lt;/strong&gt; es líder en el despliegue de aplicaciones en la nube, proporcionando servicios desde almacenamiento hasta gestión de contenedores. &lt;strong&gt;DigitalOcean&lt;/strong&gt; es popular para startups y pequeños proyectos que buscan simplicidad y costos accesibles.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Vercel&lt;/strong&gt; es ideal para desplegar aplicaciones construidas con &lt;strong&gt;Next.js&lt;/strong&gt;, con soporte para &lt;strong&gt;Serverless Functions&lt;/strong&gt; y funcionalidades optimizadas para frontend, como la capacidad de integrar funciones sin configuración adicional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;El desarrollo full stack en 2024 sigue evolucionando, y tener las herramientas adecuadas es esencial para mantenerse competitivo. Desde frameworks backend como &lt;strong&gt;Node.js&lt;/strong&gt; y &lt;strong&gt;NestJS&lt;/strong&gt; hasta herramientas de despliegue como &lt;strong&gt;Docker&lt;/strong&gt; y &lt;strong&gt;Kubernetes&lt;/strong&gt;, estas herramientas permiten a los desarrolladores crear aplicaciones escalables y eficientes. Mantenerse al día con estas tecnologías mejorará la calidad de los desarrollos y ayudará a ofrecer mejores soluciones.&lt;/p&gt;

&lt;p&gt;¿Cuáles de estas herramientas ya utilizas y cuáles planeas aprender este año? ¡Compártelo en los comentarios!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>fullstack</category>
      <category>developers</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Implementación de Autenticación Segura en Node.js con JWT</title>
      <dc:creator>Adrian Grahl</dc:creator>
      <pubDate>Wed, 09 Oct 2024 17:01:08 +0000</pubDate>
      <link>https://forem.com/adriangrahldev/implementacion-de-autenticacion-segura-en-nodejs-con-jwt-465o</link>
      <guid>https://forem.com/adriangrahldev/implementacion-de-autenticacion-segura-en-nodejs-con-jwt-465o</guid>
      <description>&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;La seguridad en las aplicaciones web es un aspecto fundamental, especialmente cuando manejamos información sensible. Una forma popular y segura de implementar autenticación en &lt;strong&gt;Node.js&lt;/strong&gt; es mediante el uso de &lt;strong&gt;JWT (JSON Web Tokens)&lt;/strong&gt;. En este artículo, te mostraré cómo crear una autenticación segura utilizando &lt;strong&gt;JWT&lt;/strong&gt; en una aplicación de Node.js, simulando una base de datos con un array para almacenar los usuarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. ¿Qué es JWT y cómo funciona?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;JWT (JSON Web Token)&lt;/strong&gt; es un estándar que define una forma compacta y segura de transmitir información entre las partes como un objeto JSON. El token está compuesto por tres partes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Header (Encabezado)&lt;/strong&gt;: Indica el tipo de token y el algoritmo de cifrado utilizado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payload (Carga útil)&lt;/strong&gt;: Contiene las declaraciones o claims, como el ID del usuario.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signature (Firma)&lt;/strong&gt;: Se usa para verificar que el token no ha sido alterado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JWT es útil para transmitir información que puede verificarse y confiarse.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Configuración del Proyecto en Node.js
&lt;/h2&gt;

&lt;p&gt;Primero, vamos a configurar un proyecto básico de &lt;strong&gt;Node.js&lt;/strong&gt; con &lt;strong&gt;Express&lt;/strong&gt; y las bibliotecas necesarias.&lt;/p&gt;

&lt;h3&gt;
  
  
  Paso 1: Crear un nuevo proyecto e instalar dependencias
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;mkdir secure-auth-nodejs&lt;br&gt;
cd secure-auth-nodejs &lt;br&gt;
npm init -y &lt;br&gt;
npm install express jsonwebtoken bcryptjs dotenv&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Express&lt;/strong&gt;: Para crear el servidor web.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jsonwebtoken&lt;/strong&gt;: Para manejar JWT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;bcryptjs&lt;/strong&gt;: Para encriptar las contraseñas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dotenv&lt;/strong&gt;: Para manejar las variables de entorno.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  3. Configuración del servidor Express
&lt;/h2&gt;

&lt;p&gt;Crea el archivo &lt;code&gt;app.js&lt;/code&gt; para inicializar el servidor &lt;strong&gt;Express&lt;/strong&gt; y configurar algunas rutas básicas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const app = express();
const dotenv = require('dotenv');
dotenv.config();

app.use(express.json()); // Permite manejar JSON en las solicitudes

app.get('/', (req, res) =&amp;gt; {
  res.send('API de autenticación segura');
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () =&amp;gt; {
  console.log(`Servidor corriendo en el puerto ${PORT}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Simulación de Base de Datos: Array de Usuarios
Para simplificar el ejemplo, utilizaremos un array para simular una base de datos de usuarios. Este array almacenará los usuarios registrados en memoria mientras la aplicación esté corriendo.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const users = []; // Simula una base de datos en memoria
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Registro de Usuario con Contraseña Encriptada
Cuando un usuario se registra, debemos encriptar su contraseña antes de guardarla. Utilizaremos bcryptjs para este propósito.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const bcrypt = require('bcryptjs');

// Ruta para registrar un nuevo usuario
app.post('/register', async (req, res) =&amp;gt; {
  const { username, password } = req.body;

  // Verificar si el usuario ya existe
  const userExists = users.find(user =&amp;gt; user.username === username);
  if (userExists) return res.status(400).send('El usuario ya existe');

  // Encriptar la contraseña
  const hashedPassword = await bcrypt.hash(password, 10);

  // Guardar usuario en la base de datos simulada
  const newUser = { username, password: hashedPassword };
  users.push(newUser);

  res.status(201).send('Usuario registrado exitosamente');
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Login y Generación de JWT
Al iniciar sesión, verificamos que el usuario exista y que la contraseña coincida. Si todo es correcto, generamos un JWT que el cliente utilizará para autenticar las solicitudes futuras.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const jwt = require('jsonwebtoken');

// Ruta para iniciar sesión
app.post('/login', async (req, res) =&amp;gt; {
  const { username, password } = req.body;

  // Buscar al usuario
  const user = users.find(u =&amp;gt; u.username === username);
  if (!user) return res.status(400).send('Usuario no encontrado');

  // Verificar la contraseña
  const validPassword = await bcrypt.compare(password, user.password);
  if (!validPassword) return res.status(400).send('Contraseña incorrecta');

  // Generar un token JWT
  const token = jwt.sign({ username: user.username }, process.env.TOKEN_SECRET, { expiresIn: '1h' });
  res.header('auth-token', token).send(token);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Proteger Rutas con JWT
Para proteger ciertas rutas de acceso, utilizaremos un middleware que verifique si el usuario tiene un token válido antes de permitir el acceso.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Middleware para verificar el token JWT
function verifyToken(req, res, next) {
  const token = req.header('auth-token');
  if (!token) return res.status(401).send('Acceso denegado');

  try {
    const verified = jwt.verify(token, process.env.TOKEN_SECRET);
    req.user = verified;
    next(); // Continuar con la solicitud
  } catch (err) {
    res.status(400).send('Token inválido');
  }
}

// Ruta protegida (solo accesible con token)
app.get('/protected', verifyToken, (req, res) =&amp;gt; {
  res.send('Accediste a una ruta protegida');
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;8. Buenas Prácticas para la Autenticación Segura&lt;/strong&gt;&lt;br&gt;
Usar HTTPS: Siempre utiliza HTTPS para proteger la comunicación entre el cliente y el servidor.&lt;/p&gt;

&lt;p&gt;Expiración del token: Establecer una duración limitada para los tokens (ejemplo: 1 hora) es una buena práctica para minimizar riesgos.&lt;/p&gt;

&lt;p&gt;Almacenamiento seguro: Almacena el JWT en una cookie con el flag httpOnly para mayor seguridad.&lt;/p&gt;

&lt;p&gt;Rotación de tokens: Implementar "refresh tokens" para manejar sesiones prolongadas de forma segura.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Implementar autenticación con JWT en Node.js es un proceso relativamente sencillo y eficaz para proteger las rutas y verificar la identidad del usuario. En este ejemplo, utilizamos un array para simular una base de datos, pero el mismo concepto puede aplicarse en producción utilizando una base de datos real. Con esta base, puedes expandir el sistema añadiendo características avanzadas como manejo de roles, permisos y renovaciones de tokens.&lt;/p&gt;

</description>
      <category>node</category>
      <category>express</category>
      <category>jwt</category>
      <category>security</category>
    </item>
  </channel>
</rss>
