Usuarios que acceden

Meggin Kearney
Meggin Kearney

Para que los usuarios accedan, recupera las credenciales del Administrador de contraseñas del navegador y úsalas para que se conecten automáticamente. Para los usuarios con varias cuentas, permíteles seleccionar la cuenta con un solo toque usando el selector de cuentas.

Acceso automático

El acceso automático puede ocurrir en cualquier parte de tu sitio web, no solo en la página principal, sino también en otras páginas secundarias. Esto es útil cuando los usuarios llegan a varias páginas de tu sitio web a través de un motor de búsqueda.

Para habilitar el acceso automático, sigue estos pasos:

  1. Obtén información de las credenciales.
  2. Autentica al usuario.
  3. Actualiza la IU o continúa a la página personalizada.

Obtén información de credenciales

Browser Support

  • Chrome: 51.
  • Edge: 18.
  • Firefox: 60.
  • Safari: 13.

Source

Para obtener información de las credenciales, invoca navigator.credentials.get(). Especifica el tipo de credenciales que se solicitarán proporcionando un password o federated.

Usa siempre mediation: 'silent' para los accesos automáticos, de modo que puedas descartar el proceso fácilmente si el usuario hace lo siguiente:

  • No tiene credenciales almacenadas.
  • Tiene varias credenciales almacenadas.
  • Si saliste de tu cuenta

Antes de obtener una credencial, no olvides verificar si el usuario ya accedió:

if (window.PasswordCredential || window.FederatedCredential) {
  if (!user.isSignedIn()) {
    navigator.credentials.get({
      password: true,
      federated: {
        providers: ['https://accounts.google.com'],
      },
      mediation: 'silent',
    });
    // ...
  }
}

La promesa que devuelve navigator.credentials.get() se resuelve con un objeto de credencial o null. Para determinar si es un PasswordCredential o un FederatedCredential, solo debes mirar la propiedad .type del objeto, que será password o federated.

Si el .type es federated, la propiedad .provider es una cadena que representa al proveedor de identidad.

Autenticar usuario

Una vez que tengas la credencial, ejecuta un flujo de autenticación según el tipo de credencial, password o federated:

    }).then(c => {
     if (c) {
       switch (c.type) {
         case 'password':
           return sendRequest(c);
           break;
         case 'federated':
           return gSignIn(c);
           break;
       }
     } else {
       return Promise.resolve();
     }

Cuando se resuelva la promesa, verifica si recibiste un objeto de credencial. De lo contrario, significa que no se pudo realizar el acceso automático. Descarta de forma silenciosa el proceso de acceso automático.

Actualiza la IU

Si la autenticación se realiza correctamente, actualiza la IU o reenvía al usuario a la página personalizada:

    }).then(profile => {
     if (profile) {
       updateUI(profile);
     }

No olvides mostrar el mensaje de error de autenticación

Para evitar confusiones, los usuarios deberían ver un mensaje de notificación azul que diga "Accediendo" cuando se obtenga el objeto de credencial:

Mensaje emergente azul que muestra que el usuario está accediendo.

Un consejo importante: Si logras obtener un objeto de credencial, pero no puedes autenticar al usuario, debes mostrar un mensaje de error:

        }).catch(error => {
          showError('Sign-in Failed');
        });
      }
    }

Ejemplo de código completo

if (window.PasswordCredential || window.FederatedCredential) {
  if (!user.isSignedIn()) {
    navigator.credentials
      .get({
        password: true,
        federated: {
          providers: ['https://accounts.google.com'],
        },
        mediation: 'silent',
      })
      .then((c) => {
        if (c) {
          switch (c.type) {
            case 'password':
              return sendRequest(c);
              break;
            case 'federated':
              return gSignIn(c);
              break;
          }
        } else {
          return Promise.resolve();
        }
      })
      .then((profile) => {
        if (profile) {
          updateUI(profile);
        }
      })
      .catch((error) => {
        showError('Sign-in Failed');
      });
  }
}

Acceso a través del selector de cuentas

Si un usuario requiere mediación o tiene varias cuentas, usa el selector de cuentas para permitir que el usuario acceda, omitiendo el formulario de acceso habitual, por ejemplo:

Selector de cuentas de Google que muestra varias cuentas.

Los pasos para acceder a través del selector de cuentas son los mismos que en el acceso automático, con una llamada adicional para mostrar el selector de cuentas como parte de la obtención de información de credenciales:

  1. Obtén la información de las credenciales y muestra el selector de cuentas.
  2. Autentica al usuario.
  3. Actualiza la IU o continúa a una página personalizada.

Obtén información de las credenciales y muestra el selector de cuentas

Muestra un selector de cuentas en respuesta a una acción definida del usuario, por ejemplo, cuando el usuario presiona el botón "Acceder". Llama a navigator.credentials.get() y agrega mediation: 'optional' o mediation: 'required' para mostrar el selector de cuentas.

Cuando mediation es required, siempre se muestra un selector de cuentas para que el usuario acceda. Esta opción permite que los usuarios con varias cuentas cambien fácilmente entre ellas. Cuando mediation es optional, se muestra de forma explícita un selector de cuentas para que el usuario acceda después de una llamada a navigator.credentials.preventSilentAccess(). Por lo general, esto se hace para garantizar que no se produzca el acceso automático después de que el usuario decida salir o cancelar el registro.

Ejemplo en el que se muestra mediation: 'optional':

    var signin = document.querySelector('#signin');
    signin.addEventListener('click', e => {
     if (window.PasswordCredential || window.FederatedCredential) {
       navigator.credentials.get({
         password: true,
         federated: {
           providers: [
             'https://accounts.google.com'
           ]
         },
         mediation: 'optional'
       }).then(c => {

Una vez que el usuario selecciona una cuenta, la promesa se resuelve con la credencial. Si el usuario cancela el selector de cuentas o no hay credenciales almacenadas, la promesa se resuelve con null. En ese caso, recurre a la experiencia del formulario de acceso.

No olvides recurrir al formulario de acceso

Deberías recurrir a un formulario de acceso por cualquiera de los siguientes motivos:

  • No se almacenan credenciales.
  • El usuario descartó el selector de cuentas sin elegir una.
  • La API no está disponible.
    }).then(profile => {
        if (profile) {
          updateUI(profile);
        } else {
          location.href = '/signin';
        }
    }).catch(error => {
        location.href = '/signin';
    });

Ejemplo de código completo

var signin = document.querySelector('#signin');
signin.addEventListener('click', (e) => {
  if (window.PasswordCredential || window.FederatedCredential) {
    navigator.credentials
      .get({
        password: true,
        federated: {
          providers: ['https://accounts.google.com'],
        },
        mediation: 'optional',
      })
      .then((c) => {
        if (c) {
          switch (c.type) {
            case 'password':
              return sendRequest(c);
              break;
            case 'federated':
              return gSignIn(c);
              break;
          }
        } else {
          return Promise.resolve();
        }
      })
      .then((profile) => {
        if (profile) {
          updateUI(profile);
        } else {
          location.href = '/signin';
        }
      })
      .catch((error) => {
        location.href = '/signin';
      });
  }
});

Acceso federado

El acceso federado permite que los usuarios accedan con un solo toque y sin tener que recordar datos de acceso adicionales para tu sitio web.

Para implementar el acceso federado, haz lo siguiente:

  1. Autentica al usuario con una identidad de terceros.
  2. Almacenar la información de identidad
  3. Actualiza la IU o continúa a una página personalizada (igual que en el acceso automático).

Autentica al usuario con una identidad de terceros

Cuando un usuario presione un botón de acceso federado, ejecuta el flujo de autenticación del proveedor de identidad específico con el FederatedCredential.

Browser Support

  • Chrome: 51.
  • Edge: 79.
  • Firefox: not supported.
  • Safari: not supported.

Source

Por ejemplo, si el proveedor es Google, usa la biblioteca de JavaScript de Acceso con Google:

navigator.credentials
  .get({
    password: true,
    mediation: 'optional',
    federated: {
      providers: ['https://account.google.com'],
    },
  })
  .then(function (cred) {
    if (cred) {
      // Instantiate an auth object
      var auth2 = gapi.auth2.getAuthInstance();

      // Is this user already signed in?
      if (auth2.isSignedIn.get()) {
        var googleUser = auth2.currentUser.get();

        // Same user as in the credential object?
        if (googleUser.getBasicProfile().getEmail() === cred.id) {
          // Continue with the signed-in user.
          return Promise.resolve(googleUser);
        }
      }

      // Otherwise, run a new authentication flow.
      return auth2.signIn({
        login_hint: id || '',
      });
    }
  });

El Acceso con Google genera un token de ID como prueba de autenticación.

En general, los accesos federados se basan en protocolos estándar, como OpenID Connect u OAuth. Para obtener información sobre cómo autenticar con cuentas federadas, consulta los documentos de los proveedores de identidad federada correspondientes. Entre los ejemplos populares, se incluyen los siguientes:

Almacena información de identidad

Una vez que se complete la autenticación, podrás almacenar la información de identidad. La información que almacenarás aquí es el id del proveedor de identidad y una cadena de proveedor que representa al proveedor de identidad (name y iconURL son opcionales). Obtén más información sobre estos datos en la especificación de administración de credenciales.

Para almacenar los detalles de la cuenta federada, crea una instancia de un objeto FederatedCredential nuevo con el identificador del usuario y el del proveedor. Luego, invoca navigator.credentials.store() para almacenar la información de identidad.

Después de una federación exitosa, crea una instancia de FederatedCredential de forma síncrona o asíncrona:

Ejemplo de enfoque síncrono:

// Create credential object synchronously.
var cred = new FederatedCredential({
  id: id, // id in IdP
  provider: 'https://account.google.com', // A string representing IdP
  name: name, // name in IdP
  iconURL: iconUrl, // Profile image url
});

Ejemplo de enfoque asíncrono:

// Create credential object asynchronously.
var cred = await navigator.credentials.create({
  federated: {
    id: id,
    provider: 'https://accounts.google.com',
    name: name,
    iconURL: iconUrl,
  },
});

Luego, almacena el objeto de credencial:

// Store it
navigator.credentials.store(cred).then(function () {
  // continuation
});

Salir

Cierra la sesión de los usuarios cuando presionen el botón para salir. Primero, finaliza la sesión y, luego, desactiva el acceso automático para las próximas visitas. (La forma en que finalices tus sesiones depende totalmente de ti).

Desactivar el acceso automático para visitas futuras

Llama al navigator.credentials.preventSilentAccess():

signoutUser();
if (navigator.credentials && navigator.credentials.preventSilentAccess) {
  navigator.credentials.preventSilentAccess();
}

Esto garantizará que el acceso automático no se produzca hasta la próxima vez que el usuario lo habilite. Para reanudar el acceso automático, el usuario puede elegir acceder de forma intencional seleccionando la cuenta con la que desea acceder en el selector de cuentas. Luego, el usuario siempre volverá a acceder hasta que salga de forma explícita.

Comentarios