Registro de Usuarios y Almacenamiento Seguro de Contraseñas
Resumen
La autenticación de usuarios es un componente fundamental en el desarrollo de aplicaciones web modernas. Implementar un sistema de registro seguro no solo protege la información de tus usuarios, sino que también establece la base para funcionalidades más avanzadas como rutas protegidas y niveles de acceso personalizados. En este contenido, exploraremos cómo crear un punto de entrada para registrar usuarios en una base de datos utilizando Node.js, Prisma ORM y técnicas de encriptación.
¿Cómo implementar un sistema de registro de usuarios seguro?
Cuando desarrollamos aplicaciones web, la seguridad de los datos de nuestros usuarios debe ser una prioridad. Implementar un sistema de registro robusto implica no solo almacenar la información del usuario, sino también proteger datos sensibles como las contraseñas mediante técnicas de encriptación.
Para crear nuestro punto de entrada de registro, necesitamos:
Configurar una ruta POST para recibir los datos del usuario
Extraer la información del cuerpo de la solicitud
Encriptar la contraseña antes de almacenarla
Guardar los datos en la base de datos
Devolver una respuesta apropiada
Creando el endpoint de registro
Primero, debemos configurar nuestra ruta POST para recibir los datos del nuevo usuario:
app.post('/register',async(req, res)=>{// Extraer información del cuerpo de la solicitudconst{ email, password, name }= req.body;// Encriptar la contraseñaconst hashedPassword =await bcrypt.hash(password,10);// Crear el usuario en la base de datosconst newUser =await prisma.user.create({data:{ email,password: hashedPassword, name,role:'user'}});// Enviar respuesta res.status(201).json({message:'User registered successfully'});});
Este código establece un punto de entrada /register que acepta solicitudes POST con los datos del usuario. La contraseña se encripta utilizando bcrypt con un factor de costo de 10, lo que proporciona un buen equilibrio entre seguridad y rendimiento.
Protegiendo las contraseñas con bcrypt
La seguridad de las contraseñas es crucial en cualquier sistema de autenticación. Nunca debemos almacenar contraseñas en texto plano en nuestra base de datos. En su lugar, utilizamos algoritmos de hash como bcrypt:
Debemos importar estas librerías al inicio de nuestro archivo para poder utilizarlas. bcrypt nos permite generar un hash seguro de la contraseña, mientras que JWT (JSON Web Token) lo utilizaremos más adelante para la autenticación.
El factor de costo (en este caso 10) determina cuánto trabajo computacional se requiere para generar el hash. Un valor más alto proporciona mayor seguridad pero consume más recursos.
Almacenando usuarios con Prisma ORM
Prisma nos facilita la interacción con la base de datos mediante un ORM (Object-Relational Mapping). Para crear un nuevo usuario, utilizamos el método create del modelo User:
Este código crea un nuevo registro en la tabla de usuarios con los datos proporcionados. El ID se genera automáticamente gracias a la configuración del modelo en Prisma.
¿Cómo probar nuestro endpoint de registro?
Una vez implementado el código, es importante verificar que funcione correctamente. Podemos utilizar herramientas como Postman para enviar solicitudes a nuestro endpoint y comprobar las respuestas.
Configurando la solicitud en Postman
Para probar nuestro endpoint de registro:
Crear una nueva solicitud POST
Establecer la URL (por ejemplo, http://localhost:3000/register)
En la pestaña "Body", seleccionar "raw" y formato JSON
Este endpoint debe eliminarse en producción ya que expone información sensible, pero es útil durante el desarrollo para verificar que:
Los IDs se generan correctamente
Las contraseñas se almacenan como hashes, no en texto plano
Los roles se asignan adecuadamente
¿Qué consideraciones de seguridad debemos tener en cuenta?
Implementar un sistema de registro seguro implica más que solo encriptar contraseñas. Algunas consideraciones importantes:
Proteger las claves secretas: El secreto utilizado para generar los hashes debe mantenerse seguro.
Eliminar endpoints de depuración: Rutas como /db/users deben eliminarse en producción.
Validar los datos de entrada: Verificar que los datos proporcionados cumplen con los requisitos (formato de email válido, contraseña suficientemente fuerte, etc.).
Implementar límites de intentos: Prevenir ataques de fuerza bruta limitando los intentos de registro desde una misma IP.
La seguridad es un proceso continuo, no una característica que se implementa una vez y se olvida. Debemos estar constantemente actualizando y mejorando nuestras prácticas de seguridad.
La implementación de un sistema de registro seguro es solo el primer paso en la creación de un sistema de autenticación completo. En próximas etapas, desarrollaremos el login de usuarios y la validación de rutas protegidas mediante tokens JWT.
¿Has implementado sistemas de autenticación en tus proyectos? ¿Qué técnicas de seguridad utilizas para proteger los datos de tus usuarios? Comparte tu experiencia en los comentarios.
el ejercicio del video esta mal configurado y la opción de 201 Created da error con su respuesta
Para que no se muestre el password podemos hacer algo asi en la consulta de prisma
app.get('/db-users',async(req, res)=>{try{const users =await prisma.user.findMany({select:{id:true,email:true,name:true,lastName:true,phone:true,role:true}}); res.status(200).json(users);}catch(error){ res
.status(500).json({error:'Error al comunicarse con la base de datos.'});}});```app.get('/db-users',async(req, res)=>{try{const users =await prisma.user.findMany({select:{id:true,email:true,name:true,lastName:true,phone:true,role:true}}); res.status(200).json(users);}catch(error){ res .status(500).json({error:'Error al comunicarse con la base de datos.'});}});
ja ja ja jaj el archovo se fue al carajo desde el ejemplo 4 con el form pero esta cool que todo funciona
Entiendo la parte que se tiene que almacenar la contraseña ya en forma de hash en la base de datos. Lo único que me causa algo de ruido es la contraseña plana en Postman. Yo en mis proyectos ya mando la contraseña en forma de hash desde Postman, y no en texto plano.
Entiendo que la información por default en producción se debería mandar a través de HTTPS y el punto anterior no tiene mucho peso.
A lo que voy es que son diferentes enfoques pero yo al menos me gusta que el back ya reciba el hash y el no lo calcule.
No deberías usar algoritmos costosos en cuanto a su rendimiento como bcrypt directamente en el frontend. Terminas usando SHA-256, MD5 u otros que no tan sseguros.
Estás reinventando la rueda, creando una especie de "firma" que no reemplaza los estándares de autenticación existentes.
Si alguien intercepta el hash (aunque improbable con HTTPS), dejando como resultado este hash como su contraseña final.
Por eso se usa HTTPS y los certificados SSL. Ya si te molesta ver la password en la network tab puedes usar SSR (Server Side Rendering) en tu frontend