Como implementar 2FA en NodeJS


2FA, o autenticación de dos factores, es un método de seguridad que agrega una capa adicional de protección a sus cuentas en línea


2FA, o autenticación de dos factores, es un método de seguridad que agrega una capa adicional de protección a sus cuentas en línea. Requiere dos formas de identificación para que alguien pueda iniciar sesión en su cuenta: su contraseña y un código de verificación de un solo uso (OTP).

  • El primer factor es su contraseña, que es lo que usa para iniciar sesión en su cuenta.
  • El segundo factor es el código OTP, que es un código aleatorio que se genera en su dispositivo móvil o en una aplicación de autenticación.


Las aplicaciones de autenticación más populares son:

  • Google Authenticator: Es una aplicación gratuita de Google que genera códigos OTP. Es compatible con una amplia gama de servicios, incluidos Gmail, Facebook, Twitter, Instagram y muchos más.
  • Microsoft Authenticator: Es una aplicación gratuita de Microsoft que genera códigos OTP. Es compatible con una amplia gama de servicios, incluidos Microsoft 365, OneDrive, Outlook y muchos más.
  • Authy: Es una aplicación gratuita que genera códigos OTP. También ofrece la opción de sincronizar sus códigos en la nube, lo que le permite acceder a ellos desde cualquier dispositivo.
  • LastPass Authenticator: Es una aplicación gratuita que genera códigos OTP. Es parte del paquete de seguridad de LastPass, que incluye un administrador de contraseñas.

Habilitando 2FA en NodeJS

Formulario de Habilitación de 2FA

En el perfil de usuario de tu aplicacion debe existir un boton que te permite habilitar para dicho usuario la autenticacion en 2 pasos.

Al activar la autenticacion en 2 pasos, el servidor en node generara una URL de activacion la cual podremos mostrar como codigo QR, el cual podra ser facilmente escaneado por alguna de las aplicaciones de autenticacion mencionadas arriba.

/*
Generamos las claves secretas que serán usadas por las aplicaciones de autenticación para validar el acceso */
const secret = speakeasy.generateSecret({length: 20, name:`${config.companyName} ${req.user.correo}`});

/*
Generamos el código QR necesario para registrar nuestro usuario en las aplicaciones de autenticación
*/
const imageQr = await QRCode.toDataURL(secret.otpauth_url, {
            type: "image/webp",
            quality: 0.8,
            width: 400,
            color: {
                dark: '#4a81d4',  // Blue dots
                light: '#FFF' // Transparent background
            }
        })

Accediendo al login

Luego de habilitar el proceso de autenticación en dos pasos, cuando dicho usuario quiera loguearse al sistema deberá ingresar un token de confirmación generado por las aplicaciones de autenticación

router.post('/login', async function(req, res, next) {

    let email = req.body.email || "";
    email = email.trim().toLowerCase();

    var filter = {
        correo: email,
        estado: 1,
    };


    const user = await Models.User.findOne({where: filter});
    if ( !user ) { } // error
    if ( user.a2fa_enable ) {
      // Lo redirijimos a la pantalla de verificacion
      res.redirect("/auth/2fa");
    }
}

En la pantalla de verificacion le pedimos al usuario ingrese el codigo generado por la aplicacion de autenticacion y lo validamos

router.post("/login2fa", async function(req,res, next){

    // ...

    const user = await Models.User.findOne({where: filter});
    if(!user){ } // error

    const tokenValidates = speakeasy.totp.verify({
        secret: user.a2fa_code,
        encoding: 'base32',
        token: req.body.token, // codigo ingresado por el usuario
        window: 6
    });

    if( !tokenValidates ){
        req.flash("error", `Código no encontrado`);
        return res.redirect("/admin/auth/login2fa");
    }

    // Usuario validado con éxito
})

Con estos pasos ya podemos darle a nuestros usuarios un nuevo nivel de seguridad en sus cuentas.

Add new comment