Implementación de Autenticación con Passport.js y Estrategia Local
Clase 7 de 20 • Curso de Backend con Node.js: Autenticación con Passport.js y JWT
Resumen
¿Cómo implementar la autenticación con Passport.js?
Passport.js es una herramienta valiosa para implementar capas de autenticación en aplicaciones web. Este middleware es flexible y admite múltiples estrategias de autenticación, como login con usuario y contraseña o a través de plataformas sociales como Facebook y Twitter. Además, Passport.js facilita la integración de nuevas estrategias sin modificar la estructura de nuestro código base.
¿Cómo instalar Passport.js y las estrategias de autenticación?
Antes de comenzar a crear estrategias, es esencial instalar las dependencias necesarias en nuestro proyecto. En la terminal, ejecutamos los siguientes comandos para instalar Passport.js y su estrategia local:
npm install passport
npm install passport-local
Estas instalaciones permitirán gestionar autenticaciones básicas mediante usuario y contraseña.
¿Cómo organizar el proyecto para gestionar estrategias?
Una buena práctica es tener un directorio específico para las estrategias de autenticación. Esto nos ayuda a mantener nuestro proyecto ordenado y escalable. Creamos una carpeta llamada utils
, y dentro de ella, un subdirectorio llamado auth
, donde colocaremos nuestras estrategias.
utils/
└── auth/
└── strategies/
└── localStrategy.js
Aquí es donde desarrollaremos la primera estrategia de autenticación usando passport-local
.
¿Cómo implementar una estrategia con Passport Local?
Para implementar nuestra estrategia local, primero debemos importar Passport y la estrategia local en nuestro index.js
dentro de auth
. Además, configuramos nuestra estrategia para manejar el login.
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
async (username, password, done) => {
// Implementación de la lógica de autenticación
}
));
Hemos definido una nueva LocalStrategy
, pero aún debe incluir la lógica de negocio para manejar un login por usuario y contraseña. Passport nos proporciona automáticamente los parámetros username
y password
, así como una función done
para manejar el resultado del proceso de autenticación.
¿Cómo integrar un servicio de usuarios?
Nuestra estrategia utiliza un servicio para buscar usuarios por email en la base de datos. Implementamos un método findByEmail
en nuestro servicio de usuarios para realizar esta búsqueda:
const UserService = (db) => {
const findByEmail = async (email) => {
// búsqueda en la base de datos
};
return { findByEmail };
};
En nuestro archivo de estrategia, necesitamos importar y usar este servicio para verificar si el usuario existe y validar su contraseña:
const userService = new UserService();
passport.use(new LocalStrategy(
async (email, password, done) => {
try {
const user = await userService.findByEmail(email);
if (!user || !user.validPassword(password)) {
return done(null, false);
}
return done(null, user);
} catch (error) {
return done(error);
}
}
));
¿Cómo manejar los errores y la respuesta exitosa?
En caso de que algo salga mal, Passport utiliza la función done
para propagar errores. Importamos Boom
para estructurar errores HTTP y enviar respuestas adecuadas:
const Boom = require('@hapi/boom');
passport.use(new LocalStrategy(
async (email, password, done) => {
try {
const user = await userService.findByEmail(email);
if (!user) {
return done(Boom.unauthorized('Email o contraseña incorrecta'), false);
}
if (!user.validPassword(password)) {
return done(Boom.unauthorized('Email o contraseña incorrecta'), false);
}
return done(null, user);
} catch (error) {
return done(error);
}
}
));
¿Cómo personalizar los nombres de los campos en la estrategia?
Si preferimos utilizar el campo email
en lugar de username
, alteramos la configuración de Passport Local antes de definir nuestra estrategia:
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
}, (email, password, done) => {
// Implementación
}));
¿Cómo integrar la estrategia en el routing?
Finalmente, conectamos nuestra estrategia con las rutas de la API. Creamos un archivo authRouter.js
en el que importamos la estrategia y definimos nuestro endpoint:
const express = require('express');
const router = express.Router();
const passport = require('passport');
router.post('/login', passport.authenticate('local', { session: false }), (req, res) => {
res.json(req.user);
});
module.exports = router;
¿Por qué necesitamos JSON Web Tokens?
Hasta ahora, hemos logrado verificar usuarios utilizando Passport.js, pero la autenticación es solo una parte del proceso. Para mantener sesiones seguras y autorizar posteriormente acciones de usuarios, los JSON Web Tokens (JWT) son cruciales. Continuaremos con los JWT en el siguiente paso para enriquecer nuestro sistema de autenticación. ¡No te lo pierdas!