Certaines des mises à jour décrites ici sont expliquées dans la session Google I/O Secure and Seamless Sign-In: Keeping Users Engaged (Connexion sécurisée et fluide : maintenir l'engagement des utilisateurs) :
Chrome 57
Chrome 57 a introduit cette modification importante dans l'API Credential Management.
Les identifiants peuvent être partagés à partir d'un autre sous-domaine
Chrome peut désormais récupérer un identifiant stocké dans un autre sous-domaine à l'aide de l'API Credential Management.
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 de sélection de compte.
Vous devez stocker explicitement le mot de passe à l'aide de navigator.credentials.store(). Ainsi, lorsqu'un utilisateur choisit un identifiant en appuyant sur la boîte de dialogue, le mot de passe est transmis et copié dans l'origine actuelle.
Une fois stocké, le mot de passe est disponible en tant qu'identifiant dans la même origine 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 l'utilisateur peut les sélectionner :
Chrome 60
Chrome 60 apporte plusieurs modifications importantes à l'API Credential Management :
L'objet
PasswordCredentialinclut désormais un mot de passe.La fonction
fetch()personnalisée n'étant 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érationmediationau lieu d'un indicateur booléenunmediated.La nouvelle méthode
navigator.credentials.create()crée des objets d'identifiants de manière asynchrone.
La détection de caractéristiques requiert votre attention
Pour savoir si l'API Credential Management permettant d'accéder aux identifiants fédérés et basés sur un mot 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 adopte une approche prudente pour gérer les mots de passe.
Il masquait les mots de passe de 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 :
Ils devaient 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 constaté que le fait de masquer les 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é d'apporter une modification.
L'API Credential Management inclut désormais un mot de passe brut dans un objet d'identification renvoyé, ce qui vous permet d'y accéder en texte brut. Vous pouvez utiliser les méthodes existantes pour transmettre les informations d'identification à votre serveur :
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).the>n(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 obsolète
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
})
Nous vous recommandons d'utiliser une fonction fetch() standard, comme illustré dans l'exemple de code précédent, ou d'utiliser un XMLHttpRequest.
navigator.credentials.get() accepte désormais une énumération de médiation.
Jusqu'à Chrome 60, navigator.credentials.get() acceptait une propriété unmediated facultative avec un flag 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'un identifiant.
Le flag est désormais é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 |
Par rapport à l'option booléenne | Comportement | |
|---|---|---|---|
silent |
Égal à unmediated: true |
Identifiant transmis sans afficher de sélecteur de compte. | |
optional |
Égal à unmediated: false |
Affiche un sélecteur de compte si preventSilentAccess() a été appelé précédemment. |
|
required |
Une nouvelle option | Toujours afficher un sélecteur de compte. Utile lorsque vous souhaitez permettre à un utilisateur de changer de compte à l'aide de la boîte de dialogue native de sélection de compte. |
Dans cet exemple, l'identifiant est transmis sans afficher de sélecteur de compte, ce qui équivaut à l'option précédente, unmediated: true :
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent&>#39;
}).then(c = {
// Sign-in
});
Remplacement du nom requireUserMediation() par preventSilentAccess().
Pour s'aligner correctement sur 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 de transmettre des identifiants sans afficher le sélecteur de compte (parfois appelé "sans médiation de l'utilisateur"). Cela est utile lorsqu'un utilisateur se déconnecte d'un site Web ou se désinscrit, et qu'il ne souhaite pas être reconnecté automatiquement lors de sa prochaine visite.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
Créez des objets d'identifiants de manière asynchrone avec la nouvelle méthode navigator.credentials.create().
Vous pouvez désormais créer des objets d'identifiants de manière asynchrone avec la nouvelle méthode navigator.credentials.create().
Lisez la suite pour comparer les approches synchrone et asynchrone.
Créer un objet PasswordCredential
Approche de synchronisation
let c = new PasswordCredential(form);
Approche asynchrone (nouvelle)
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 synchronisation
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
Approche asynchrone (nouvelle)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 39;https://*****'
}
});
Guide de migration
Vous avez déjà implémenté l'API Credential Management ? Nous avons un guide de migration que vous pouvez suivre pour passer à la nouvelle version.