Certaines des nouveautés décrites ici sont expliquées dans la session Google I/O, Connexion fluide et sécurisée: favoriser l'engagement des utilisateurs:
Chrome 57
Chrome 57 a introduit cette modification importante API Credential Management
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 la
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 du sélecteur de compte.
Vous devez explicitement stocker 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é
à l'origine actuelle.
Une fois stocké, le mot de passe est disponible en tant qu'identifiant
ayant exactement la même origine www.example.com
et au-delà.
Dans la capture d'écran suivante, les informations d'identification stockées sous login.aliexpress.com
est visible par m.aliexpress.com
et peut être sélectionnée par l'utilisateur:
![Sélecteur de compte affichant les informations de connexion du sous-domaine sélectionné](https://developer.chrome.com/static/blog/credential-management-updates/image/account-chooser-showing-s-369ff3f4bb61e.png?authuser=19&hl=fr)
Chrome 60
Chrome 60 introduit plusieurs modifications importantes API Credential Management:
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 abandonnée.navigator.credentials.get()
accepte désormais une énumérationmediation
au lieu de l'indicateur booléenunmediated
.Nouvelle méthode
navigator.credentials.create()
crée des objets d'identification de manière asynchrone.
La détection de caractéristiques requiert votre attention
Pour voir si l'API de gestion des identifiants permet d'accéder aux services
les identifiants fédérés 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 conservatrice pour gérer les mots de passe.
Il a dissimulé les mots de passe de JavaScript, ce qui oblige les développeurs
d'envoyer l'objet PasswordCredential
directement à son serveur
pour la validation via une extension de l'API fetch()
.
Mais 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.
Ils devaient envoyer la valeur de hachage du mot de passe à leur serveur.
Après avoir réalisé une analyse de sécurité et identifié que le fait de dissimuler des mots de passe de JavaScript n'a pas empêché tous les vecteurs d'attaque aussi efficacement que nous l'espérions, nous avons décidé d'effectuer un changement.
L'API Credential Management inclut désormais un mot de passe brut dans un objet d'identification renvoyé afin 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'
}).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, procédez comme suit :
vérifiez s'il utilise un objet PasswordCredential
ou FederatedCredential
en tant que valeur de la propriété credentials
, par exemple:
fetch('/signin', {
method: 'POST',
credentials: c
})
À l'aide d'une fonction fetch()
standard, comme illustré dans l'exemple de code précédent,
ou l'utilisation d'un XMLHttpRequest
est recommandé.
navigator.credentials.get()
accepte désormais une médiation d'énumération.
Jusqu'à Chrome 60,
navigator.credentials.get()
a accepté 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 désormais étendu en tant que médiation. La médiation de l'utilisateur peut avoir lieu dans les cas suivants:
Un 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 sans qu'un sélecteur de compte ne s'affiche. | |
optional |
Est égal(e) à unmediated: false |
Affiche un sélecteur de compte si
preventSilentAccess() appelé précédemment. |
|
required |
Une nouvelle option | Toujours afficher un sélecteur de compte Utile lorsque vous souhaitez autoriser un utilisateur à changer de compte à l'aide de la boîte de dialogue du sélecteur de compte natif. |
Dans cet exemple,
les identifiants sont transmis sans
afficher de sélecteur de compte,
l'équivalent de l'option précédente, 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 bien s'aligner sur la nouvelle propriété mediation
proposée dans l'appel get()
,
la méthode navigator.credentials.requireUserMediation()
a été renommée en
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). Cette fonctionnalité est utile lorsqu'un utilisateur se déconnecte d'un site Web ou se désinscrit d'un site. d'un utilisateur et ne veut 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 désormais la possibilité de créer des objets d'identification de manière asynchrone
à l'aide de la nouvelle méthode navigator.credentials.create()
.
Poursuivez votre lecture pour comparer les deux approches, avec celles basées sur la synchronisation et l'approche asynchrone.
Créer un objet PasswordCredential
Approche de la 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 la 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: 'https://*****'
}
});
Guide de migration
Vous avez déjà implémenté l'API Credential Management ? Nous mettons à votre disposition un guide de migration. vous pouvez suivre pour passer à la nouvelle version.