Administra los usuarios que usan autenticación de varios factores

En este documento, se muestra cómo usar Firebase Admin SDK para administrar los usuarios de varios factores de manera programática. Cuando administras estos usuarios, puedes acceder a un rango aumentado de propiedades del usuario en comparación con los usuarios que usan un solo factor.

Antes de comenzar

Instala el Admin SDK de Node.js. Por el momento, no se admiten otros idiomas de Admin SDK.

Obtén usuarios

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

En el siguiente ejemplo, se muestra un usuario inscrito en la autenticación de varios factores:

// 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',
      },
    ],
  },
};

Enumera los usuarios

En el código que aparece a continuación, se muestra cómo obtener una lista de todos los usuarios y verificar si tienen un factor secundario inscrito:

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 muestran por lotes, ordenados según su uid. Cada lote de resultados contiene una lista de usuarios y un token de página siguiente que se usa para recuperar el siguiente lote. Después de que se enumeran todos los usuarios, no se muestra ningún pageToken.

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

Crea un usuario

Llama a createUser() para crear un usuario nuevo. Los usuarios nuevos con factores secundarios deben tener una dirección de correo electrónico verificada (configura emailVerified como true) y usar un primer factor admitido para acceder. Se permiten hasta 5 factores secundarios por usuario.

En el ejemplo, se muestra cómo crear un usuario nuevo con 2 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);
});

Actualiza un usuario

Para actualizar un usuario existente, 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);
});

Agrega un nuevo factor secundario

Si se llama a updateUser() con una lista de enrolledFactors, se borrarán los factores secundarios actuales del usuario. Para agregar un factor secundario nuevo y, a la vez, conservar los existentes, primero busca al usuario y, luego, agrega 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);
    });
}

Quita un factor secundario

Para dar de baja por completo a un usuario de la autenticación de varios factores, configura enrolledFactors como null o como un array vacío:

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