Para proporcionar una experiencia del usuario sofisticada, es importante ayudar a los usuarios a autenticarse en tu sitio web. Los usuarios autenticados pueden interactuar entre sí con un perfil dedicado, sincronizar datos en varios dispositivos o procesar datos sin conexión, y la lista sigue y sigue. Sin embargo, crear, recordar y escribir contraseñas suele ser engorroso para los usuarios finales, en especial en pantallas de dispositivos móviles, lo que los lleva a volver a usar las mismas contraseñas en diferentes sitios. Por supuesto, esto es un riesgo de seguridad.
La versión más reciente de Chrome (51) admite la API de Credential Management. Es una propuesta de seguimiento de estándares en el W3C que les brinda a los desarrolladores acceso programático al administrador de credenciales de un navegador y ayuda a los usuarios a acceder con mayor facilidad.
¿Qué es la API de Credential Management?
La API de Credential Management permite a los desarrolladores almacenar y recuperar credenciales de contraseña y credenciales federadas, y proporciona 3 funciones:
navigator.credentials.get()
navigator.credentials.store()
navigator.credentials.requireUserMediation()
Con estas APIs simples, los desarrolladores pueden realizar acciones potentes, como las siguientes:
- Permite que los usuarios accedan con un solo toque.
- Recuerda la cuenta federada que usó el usuario para acceder.
- Permite que los usuarios vuelvan a acceder cuando venza una sesión.
En la implementación de Chrome, las credenciales se almacenarán en el administrador de contraseñas de Chrome. Si los usuarios accedieron a Chrome, pueden sincronizar sus contraseñas en todos los dispositivos. Esas contraseñas sincronizadas también se pueden compartir con apps para Android que hayan integrado la API de Smart Lock para contraseñas para Android para obtener una experiencia multiplataforma fluida.
Cómo integrar la API de Credential Management en tu sitio
La forma en que usas la API de Credential Management con tu sitio web puede variar según su arquitectura. ¿Es una app de una sola página? ¿Es una arquitectura heredada con transiciones de página? ¿El formulario de acceso solo se encuentra en la parte superior de la página? ¿Los botones de acceso se encuentran en todas partes? ¿Los usuarios pueden navegar de forma significativa por tu sitio web sin acceder? ¿La federación funciona en ventanas emergentes? ¿O requiere interacción en varias páginas?
Es casi imposible abarcar todos esos casos, pero veamos una app de una sola página típica.
- La página superior es un formulario de registro.
- Si presionan el botón "Acceder", los usuarios navegarán a un formulario de acceso.
- Tanto los formularios de registro como los de acceso tienen las opciones típicas de credenciales de ID o contraseña y de integración, p.ej., con el Acceso con Google y el Acceso con Facebook.
Si usas la API de Credential Management, podrás agregar las siguientes funciones al sitio, por ejemplo:
- Mostrar un selector de cuentas cuando se accede: Muestra una IU nativa del selector de cuentas cuando un usuario presiona "Acceder".
- Almacena las credenciales: Cuando accedas correctamente, ofrece almacenar la información de las credenciales en el administrador de contraseñas del navegador para usarlas más adelante.
- Permitir que el usuario vuelva a acceder automáticamente: Permite que el usuario vuelva a acceder si una sesión venció.
- Mediar el acceso automático: Una vez que un usuario salga de su cuenta, inhabilita el acceso automático para la próxima visita del usuario.
Puedes experimentar estas funciones implementadas en un sitio de demostración con su código de muestra.
Mostrar el selector de cuentas cuando accedas
Entre el momento en que el usuario presiona un botón "Acceder" y la navegación a un formulario de acceso, puedes usar navigator.credentials.get() para obtener información de credenciales. Chrome mostrará una IU del selector de cuentas desde la que el usuario puede elegir una cuenta.
Cómo obtener un objeto de credencial de contraseña
Para mostrar las credenciales de contraseña como opciones de la cuenta, usa password: true
.
navigator.credentials.get({
password: true, // `true` to obtain password credentials
}).then(function(cred) {
// continuation
...
Cómo usar una credencial de contraseña para acceder
Una vez que el usuario seleccione una cuenta, la función de resolución recibirá una credencial de contraseña. Puedes enviarlo al servidor con fetch()
:
// continued from previous example
}).then(function(cred) {
if (cred) {
if (cred.type == 'password') {
// Construct FormData object
var form = new FormData();
// Append CSRF Token
var csrf_token = document.querySelector('csrf_token').value;
form.append('csrf_token', csrf_token);
// You can append additional credential data to `.additionalData`
cred.additionalData = form;
// `POST` the credential object as `credentials`.
// id, password and the additional data will be encoded and
// sent to the url as the HTTP body.
fetch(url, { // Make sure the URL is HTTPS
method: 'POST', // Use POST
credentials: cred // Add the password credential object
}).then(function() {
// continuation
});
} else if (cred.type == 'federated') {
// continuation
Cómo usar una credencial federada para acceder
Para mostrar cuentas federadas a un usuario, agrega federated
, que toma un array de proveedores de identidad, a las opciones de get()
.
navigator.credentials.get({
password: true, // `true` to obtain password credentials
federated: {
providers: [ // Specify an array of IdP strings
'https://accounts.google.com',
'https://www.facebook.com'
]
}
}).then(function(cred) {
// continuation
...
Puedes examinar la propiedad type
del objeto de credencial para ver si es PasswordCredential
(type == 'password'
) o FederatedCredential
(type == 'federated'
). Si la credencial es FederatedCredential
, puedes llamar a la API adecuada con la información que contiene.
});
} else if (cred.type == 'federated') {
// `provider` contains the identity provider string
switch (cred.provider) {
case 'https://accounts.google.com':
// Federated login using Google Sign-In
var auth2 = gapi.auth2.getAuthInstance();
// In Google Sign-In library, you can specify an account.
// Attempt to sign in with by using `login_hint`.
return auth2.signIn({
login_hint: cred.id || ''
}).then(function(profile) {
// continuation
});
break;
case 'https://www.facebook.com':
// Federated login using Facebook Login
// continuation
break;
default:
// show form
break;
}
}
// if the credential is `undefined`
} else {
// show form
Almacena las credenciales
Cuando un usuario accede a tu sitio web con un formulario, puedes usar navigator.credentials.store() para almacenar la credencial. Se le pedirá al usuario que lo almacene o no. Según el tipo de credencial, usa new
PasswordCredential()
o new
FederatedCredential()
para crear un objeto de credencial que quieras almacenar.
Cómo crear y almacenar una credencial de contraseña a partir de un elemento de formulario
En el siguiente código, se usan atributos autocomplete
para asignar automáticamente los elementos del formulario a los parámetros del objeto PasswordCredential.
HTML
html
<form id="form" method="post">
<input type="text" name="id" autocomplete="username" />
<input type="password" name="password" autocomplete="current-password" />
<input type="hidden" name="csrf_token" value="******" />
</form>
JavaScript
var form = document.querySelector('\#form');
var cred = new PasswordCredential(form);
// Store it
navigator.credentials.store(cred)
.then(function() {
// continuation
});
Crea y almacena una credencial federada
// After a federation, create a FederatedCredential object using
// information you have obtained
var cred = new FederatedCredential({
id: id, // The id for the user
name: name, // Optional user name
provider: 'https://accounts.google.com', // A string that represents the identity provider
iconURL: iconUrl // Optional user avatar image url
});
// Store it
navigator.credentials.store(cred)
.then(function() {
// continuation
});
Permite que el usuario vuelva a acceder automáticamente
Cuando un usuario sale de tu sitio web y regresa más tarde, es posible que la sesión haya caducado. No molestes al usuario para que escriba su contraseña cada vez que regrese. Permite que el usuario vuelva a acceder automáticamente.
Cómo obtener un objeto de credencial
navigator.credentials.get({
password: true, // Obtain password credentials or not
federated: { // Obtain federation credentials or not
providers: [ // Specify an array of IdP strings
'https://accounts.google.com',
'https://www.facebook.com'
]
},
unmediated: true // `unmediated: true` lets the user automatically sign in
}).then(function(cred) {
if (cred) {
// auto sign-in possible
...
} else {
// auto sign-in not possible
...
}
});
El código debería verse similar al que viste en la sección "Mostrar selector de cuenta cuando se accede". La única diferencia es que configurarás unmediated: true
.
Esto resuelve la función de inmediato y te brinda la credencial para que el usuario acceda automáticamente. Existen algunas condiciones:
- El usuario aceptó la función de acceso automático en una cálida bienvenida.
- El usuario accedió al sitio web anteriormente con la API de Credential Management.
- El usuario solo tiene una credencial almacenada para tu origen.
- El usuario no salió de la cuenta de forma explícita en la sesión anterior.
Si no se cumple alguna de estas condiciones, se rechazará la función.
Mediar el acceso automático
Cuando un usuario cierra sesión en tu sitio web, es tu responsabilidad asegurarte de que no vuelva a acceder automáticamente. Para garantizar esto, la API de Credential Management proporciona un mecanismo llamado mediación.
Para habilitar el modo de mediación, llama a navigator.credentials.requireUserMediation()
.
Siempre que el estado de mediación del usuario para el origen esté activado, si usas unmediated: true
con navigator.credentials.get()
, esa función se resolverá con undefined
.
Mediación del acceso automático
navigator.credentials.requireUserMediation();
Preguntas frecuentes
¿Es posible que JavaScript en el sitio web recupere una contraseña sin procesar?
No. Solo puedes obtener contraseñas como parte de PasswordCredential
, y no se pueden exponer de ninguna manera.
¿Es posible almacenar 3 conjuntos de dígitos para un ID con la API de Credential Management? En este momento, no. Valoraremos mucho tus comentarios sobre la especificación.
¿Puedo usar la API de Credential Management dentro de un iframe?
La API se restringe a contextos de nivel superior. Las llamadas a .get()
o .store()
en un iframe se resolverán de inmediato sin efecto.
¿Puedo integrar mi extensión de administración de contraseñas de Chrome con la API de Credential Management?
Puedes anular navigator.credentials
y conectarlo a tu extensión de Chrome para las credenciales de get()
o store()
.
Recursos
Para obtener más información sobre la API de Credential Management, consulta la Guía de integración.