Certaines des mises à jour décrites ici sont expliquées dans la session Google I/O intitulée Connexion sécurisée et fluide: maintenir l'engagement des utilisateurs:
Chrome 57
Chrome 57 a introduit cette modification importante dans l'API de gestion des identifiants.
Les identifiants peuvent être partagés depuis un autre sous-domaine
Chrome peut désormais récupérer des identifiants stockés dans un autre sous-domaine à l'aide de l'API de gestion des identifiants.
Par exemple, si un mot de passe est stocké dans login.example.com
, un script sur www.example.com
peut l'afficher comme l'un des éléments de compte dans la boîte de dialogue du sélecteur de compte.
Vous devez stocker explicitement le mot de passe à l'aide de navigator.credentials.store()
, de sorte que lorsqu'un utilisateur sélectionne un identifiant en appuyant sur la boîte de dialogue, le mot de passe est transmis et copié sur l'origine actuelle.
Une fois stocké, le mot de passe est disponible en tant qu'identifiant, à partir du même identifiant (www.example.com
).
Dans la capture d'écran suivante, les informations d'identification stockées sous login.aliexpress.com
sont visibles par m.aliexpress.com
et peuvent être sélectionnées par l'utilisateur:
Chrome 60
Chrome 60 apporte plusieurs modifications importantes à l'API de gestion des identifiants:
L'objet
PasswordCredential
inclut désormais un mot de passe.Comme la fonction
fetch()
personnalisée n'est plus nécessaire pour récupérer le mot de passe, elle sera bientôt obsolète.navigator.credentials.get()
accepte désormais une énumérationmediation
au lieu de l'indicateur booléenunmediated
.La nouvelle méthode
navigator.credentials.create()
crée des objets d'identification de manière asynchrone.
La détection des fonctionnalités requiert votre attention
Pour savoir si l'API Credential Management permettant d'accéder à des identifiants fédérés et basés sur des mots de passe est disponible, vérifiez si window.PasswordCredential
ou window.FederatedCredential
est disponible.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
L'objet PasswordCredential
inclut désormais un mot de passe
L'API Credential Management a adopté une approche prudente concernant la gestion des mots de passe.
Elle a dissimulé les mots de passe à JavaScript, ce qui obligeait les développeurs à envoyer l'objet PasswordCredential
directement à leur serveur pour validation via une extension de l'API fetch()
.
Toutefois, cette approche a introduit un certain nombre de restrictions. Nous avons reçu des commentaires indiquant que les développeurs ne pouvaient pas utiliser l'API pour les raisons suivantes:
Il devait envoyer le mot de passe dans un objet JSON.
Il devait envoyer la valeur de hachage du mot de passe à son serveur.
Après avoir effectué une analyse de sécurité et réalisé que la dissimulation des mots de passe de JavaScript n'empêchait pas tous les vecteurs d'attaque aussi efficacement que nous l'espérions, nous avons décidé de procéder à un changement.
L'API Credential Management inclut désormais un mot de passe brut dans un objet d'identification renvoyé afin que vous puissiez y accéder en texte brut. Vous pouvez utiliser des méthodes existantes pour transmettre des informations d'identification à votre serveur:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(passwordCred => {
if (passwordCred) {
let form = new FormData();
form.append('email', passwordCred.id);
form.append('password', passwordCred.password);
form.append('csrf_token', csrf_token);
return fetch('/signin', {
method: 'POST',
credentials: 'include',
body: form
});
} else {
// Fallback to sign-in form
}
}).then(res => {
if (res.status === 200) {
return res.json();
} else {
throw 'Auth failed';
}
}).then(profile => {
console.log('Auth succeeded', profile);
});
La récupération personnalisée sera bientôt abandonnée
Pour déterminer si vous utilisez une fonction fetch()
personnalisée, vérifiez si elle utilise un objet PasswordCredential
ou un objet FederatedCredential
comme valeur de la propriété credentials
, par exemple:
fetch('/signin', {
method: 'POST',
credentials: c
})
Il est recommandé d'utiliser une fonction fetch()
standard comme indiqué dans l'exemple de code précédent ou un élément XMLHttpRequest
.
navigator.credentials.get()
accepte désormais une médiation enum.
Jusqu'à Chrome 60, navigator.credentials.get()
acceptait une propriété unmediated
facultative avec un indicateur booléen. Exemple :
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).then(c => {
// Sign-in
});
La définition de unmediated: true
empêche le navigateur d'afficher le sélecteur de compte lors de la transmission d'identifiants.
L'indicateur est maintenant étendu en tant que médiation. La médiation de l'utilisateur peut se produire dans les cas suivants:
L'utilisateur doit choisir un compte avec lequel se connecter.
Un utilisateur souhaite se connecter explicitement après l'appel
navigator.credentials.requireUseMediation()
.
Choisissez l'une des options suivantes pour la valeur mediation
:
Valeur mediation |
Comparaison avec l'indicateur booléen | Comportement | |
---|---|---|---|
silent |
Est égal(e) à unmediated: true |
Identifiants transmis, mais aucun sélecteur de compte n'est affiché. | |
optional |
Est égal(e) à unmediated: false |
Affiche un sélecteur de compte si preventSilentAccess() a été appelé précédemment. |
|
required |
Nouvelle option | Toujours afficher un sélecteur de compte Cette approche est utile lorsque vous souhaitez autoriser un utilisateur à changer de compte à l'aide de la boîte de dialogue native du sélecteur de compte. |
Dans cet exemple, l'identifiant est transmis sans afficher de sélecteur de compte, l'équivalent de l'indicateur précédent, unmediated: true
:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
Remplacement du nom requireUserMediation()
par preventSilentAccess()
.
Pour s'aligner parfaitement avec la nouvelle propriété mediation
proposée dans l'appel get()
, la méthode navigator.credentials.requireUserMediation()
a été renommée navigator.credentials.preventSilentAccess()
.
La méthode renommée empêche la transmission d'identifiants sans afficher le sélecteur de compte (parfois appelée sans médiation de l'utilisateur). Cela est utile lorsqu'un utilisateur se déconnecte d'un site Web ou s'en désinscrit et ne souhaite pas se reconnecter automatiquement à sa prochaine visite.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
Créer des objets d'identification de manière asynchrone avec la nouvelle méthode navigator.credentials.create()
Vous avez maintenant la possibilité de créer des objets d'identification de manière asynchrone avec la nouvelle méthode navigator.credentials.create()
.
Vous trouverez ci-dessous une comparaison entre les approches synchrone et asynchrone.
Créer un objet PasswordCredential
Approche de la synchronisation
let c = new PasswordCredential(form);
Approche asynchrone (nouveauté)
let c = await navigator.credentials.create({
password: form
});
ou :
let c = await navigator.credentials.create({
password: {
id: id,
password: password
}
});
Créer un objet FederatedCredential
Approche de la synchronisation
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
Approche asynchrone (nouveauté)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
}
});
Guide de migration
Vous disposez déjà d'une implémentation de l'API Credential Management ? Nous disposons d'un guide de migration que vous pouvez suivre pour passer à la nouvelle version.