Gestionar usuarios que utilicen la autenticación multifactor de forma programática

En este documento se explica cómo usar el SDK de administrador de Identity Platform para gestionar a los usuarios que utilicen la autenticación multifactor de forma programática. Al gestionar usuarios que utilicen la autenticación multifactor, tienes acceso a un mayor número de propiedades de usuario que con los usuarios que utilizan la autenticación de un solo factor.

Antes de empezar

Conseguir usuarios

Puedes obtener datos relacionados con la autenticación de varios factores de los usuarios, como una lista de segundos factores registrados, del objeto UserRecord. Para obtener un registro de usuario, llama a getUser() o getUserByEmail().

En el ejemplo siguiente se muestra un usuario con la autenticación multifactor habilitada:

// console.log(userRecord.toJSON());
{
  uid: 'some-uid',
  displayName: 'John Doe',
  email: 'johndoe@gmail.com',
  photoURL: 'http://www.example.com/12345678/photo.png',
  emailVerified: true,
  phoneNumber: '+11234567890',
  // Set this user as admin.
  customClaims: {admin: true},
  // User with Google provider.
  providerData: [{
    uid: 'google-uid',
    email: 'johndoe@gmail.com',
    displayName: 'John Doe',
    photoURL: 'http://www.example.com/12345678/photo.png',
    providerId: 'google.com'
  }],
  multiFactor: {
    enrolledFactors: [
      // 2FA with SMS as 2nd factor.
      {
        uid: '53HG4HG45HG8G04GJ40J4G3J',
        phoneNumber: '+16505551234',
        displayName: 'Work phone',
        enrollmentTime: 'Fri, 22 Sep 2017 01:49:58 GMT',
        factorId: 'phone',
      },
    ],
  },
};

Enumerar usuarios

El código siguiente muestra cómo obtener una lista de todos los usuarios y comprobar si tienen registrado un factor secundario:

admin.auth().listUsers(1000, nextPageToken)
  .then((listUsersResult) => {
    listUsersResult.users.forEach((userRecord) => {
      // Multi-factor enrolled users second factors can be retrieved via:
      if (userRecord.multiFactor) {
        userRecord.multiFactor.enrolledFactors.forEach((enrolledFactor) => {
          console.log(userRecord.uid, enrolledFactor.toJSON());
        });
      }
    });
  })
  .catch((error) => {
    console.log('Error listing users:', error);
  });

Los usuarios se devuelven en lotes, ordenados por su uid. Cada lote de resultados contiene una lista de usuarios y un token de página siguiente que se usa para obtener el siguiente lote. Cuando se hayan enumerado todos los usuarios, no se devolverá ningún pageToken.

El campo maxResult especifica el tamaño máximo del lote. El valor predeterminado y máximo es 1000.

Crear un usuario

Llama a createUser() para crear un usuario. Los usuarios nuevos con factores secundarios deben tener una dirección de correo verificada (emailVerified debe estar configurado como true) y usar un primer factor compatible para iniciar sesión. Se permiten hasta 5 factores secundarios por usuario.

En el ejemplo se muestra cómo crear un usuario con dos factores secundarios:

admin.auth().createUser({
  uid: '123456789',
  email: 'user@example.com',
  emailVerified: true,
  password: 'password',
  multiFactor: {
    enrolledFactors: [
      // When creating users with phone second factors, the uid and
      // enrollmentTime should not be specified. These will be provisioned by
      // the Auth server.
      // Primary second factor.
      {
        phoneNumber: '+16505550001',
        displayName: 'Corp phone',
        factorId: 'phone',
      },
      // Backup second factor.
      {
        phoneNumber: '+16505550002',
        displayName: 'Personal phone',
        factorId: 'phone'
      },
    ],
  },
})
.then((userRecord) => {
  console.log(userRecord.multiFactor.enrolledFactors);
})
.catch((error) => {
  console.log(error);
});

Actualizar un usuario

Para actualizar un usuario, llama a updateUser():

admin.auth().updateUser(uid: '123456789', {
  multiFactor: {
    enrolledFactors: [
      {
        // uid will be auto-generated.
        phoneNumber: '+16505550003',
        displayName: 'Spouse\'s phone',
        factorId: 'phone',
      },
      {
        // uid can also be specified. This is useful if a new second factor is added and an
        // existing enrolled second factor is kept unmodified.
        uid: 'existing-enrolled-mfa-uid',
        phoneNumber: '+16505550004',
        displayName: 'Personal phone',
        factorId: 'phone',
      },
      {
        phoneNumber: '+16505550005',
        displayName: 'Backup phone',
        factorId: 'phone',
        // Enrollment time can also be explicitly specified.
        enrollmentTime: new Date().toUTCString(),
      },
    ],
  },
})
.then((userRecord) => {
  console.log(userRecord.multiFactor.enrolledFactors);
})
.catch((error) => {
  console.log(error);
});

Añadir un nuevo factor secundario

Si llamas a updateUser() con una lista de enrolledFactors, se borrarán los factores secundarios actuales del usuario. Para añadir un nuevo factor secundario sin eliminar los que ya tiene, primero busca al usuario y, a continuación, añade el nuevo factor a la lista:

function enrollSecondFactor(userId, secondFactorPhoneNumber, secondFactorDisplayName) {
  return admin.auth().getUser(userId)
    .then((userRecord) => {
      const updatedList = (userRecord.multiFactor &&
        userRecord.multiFactor.toJSON().enrolledFactors) || [];
      updatedList.push({
        phoneNumber: secondFactorPhoneNumber,
        displayName: secondFactorDisplayName,
        factorId: 'phone',
      });
      return admin.auth().updateUser(userRecord.uid, {
        multiFactor: {
          enrolledFactors: updatedList,
        },
      });
    })
    .catch((error) => {
      console.log(error);
    });
}

Eliminar un factor secundario

Para cancelar por completo el registro de un usuario en la autenticación multifactor, asigna el valor null o una matriz vacía a enrolledFactors:

admin.auth().updateUser(uid: '123456789', {
  multiFactor: {
    enrolledFactors: null,
  },
})
.then((userRecord) => {
  console.log(userRecord.multiFactor);
})
.catch((error) => {
  console.log(error);
});

Siguientes pasos