Sommige van de hier beschreven updates worden uitgelegd in de Google I/O-sessie, Veilig en naadloos inloggen: gebruikers betrokken houden :
Chroom 57
Chrome 57 introduceerde deze belangrijke wijziging in de Credential Management API .
Inloggegevens kunnen worden gedeeld vanuit een ander subdomein
Chrome kan nu een inloggegevens ophalen die in een ander subdomein zijn opgeslagen met behulp van de Credential Management API . Als een wachtwoord bijvoorbeeld is opgeslagen in login.example.com
, kan een script op www.example.com
dit weergeven als een van de accountitems in het accountkiezerdialoogvenster.
U moet het wachtwoord expliciet opslaan met navigator.credentials.store()
, zodat wanneer een gebruiker een referentie kiest door op het dialoogvenster te tikken, het wachtwoord wordt doorgegeven en naar de huidige oorsprong wordt gekopieerd.
Zodra het wachtwoord is opgeslagen, is het beschikbaar als referentie in exact dezelfde oorsprong, www.example.com
en later.
In de volgende schermafbeelding is de inloggegevens opgeslagen onder login.aliexpress.com
zichtbaar voor m.aliexpress.com
en kan de gebruiker kiezen uit:
Chroom 60
Chrome 60 introduceert verschillende belangrijke wijzigingen in de Credential Management API :
Omdat de aangepaste functie
fetch()
niet langer nodig is om het wachtwoord op te halen, wordt deze binnenkort beëindigd .navigator.credentials.get()
accepteert nu een enummediation
in plaats van een booleaanse vlagunmediated
.requireUserMediation()
hernoemd naarpreventSilentAccess()
.Nieuwe methode
navigator.credentials.create()
maakt asynchroon referentieobjecten.
Functiedetectie heeft aandacht nodig
Om te zien of de Credential Management API voor toegang tot op wachtwoord gebaseerde en federatieve referenties beschikbaar is, controleert u of window.PasswordCredential
of window.FederatedCredential
beschikbaar is.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
PasswordCredential
object bevat nu een wachtwoord
De Credential Management API hanteerde een conservatieve benadering bij het omgaan met wachtwoorden. Het verborg wachtwoorden voor JavaScript, waardoor ontwikkelaars het PasswordCredential
object rechtstreeks naar hun server moesten sturen voor validatie via een uitbreiding van de fetch()
API.
Maar deze aanpak bracht een aantal beperkingen met zich mee. We hebben feedback ontvangen dat ontwikkelaars de API niet konden gebruiken omdat:
Ze moesten het wachtwoord verzenden als onderdeel van een JSON-object.
Ze moesten de hashwaarde van het wachtwoord naar hun server sturen.
Nadat we een beveiligingsanalyse hadden uitgevoerd en beseften dat het verbergen van wachtwoorden voor JavaScript niet alle aanvalsvectoren zo effectief kon voorkomen als we hadden gehoopt, hebben we besloten een wijziging aan te brengen.
De Credential Management API bevat nu een onbewerkt wachtwoord in een geretourneerd referentieobject, zodat u er als platte tekst toegang toe heeft. U kunt bestaande methoden gebruiken om inloggegevens aan uw server te leveren:
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);
});
Aangepast ophalen wordt binnenkort beëindigd
Om te bepalen of u een aangepaste fetch()
functie gebruikt, controleert u of deze een PasswordCredential
object of een FederatedCredential
object gebruikt als waarde van de eigenschap credentials
, bijvoorbeeld:
fetch('/signin', {
method: 'POST',
credentials: c
})
Het wordt aanbevolen om een reguliere fetch()
functie te gebruiken, zoals weergegeven in het vorige codevoorbeeld, of om een XMLHttpRequest
te gebruiken.
navigator.credentials.get()
accepteert nu een enum-bemiddeling
Tot Chrome 60 accepteerde navigator.credentials.get()
een optionele unmediated
eigenschap met een Booleaanse vlag. Bijvoorbeeld:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).then(c => {
// Sign-in
});
Instelling unmediated: true
voorkomt dat de browser de accountkiezer toont bij het doorgeven van een inloggegevens.
De vlag is nu uitgebreid als bemiddeling. De gebruikersbemiddeling kan plaatsvinden wanneer:
Een gebruiker moet een account kiezen om mee in te loggen.
Een gebruiker wil zich expliciet aanmelden na de aanroep van
navigator.credentials.requireUseMediation()
.
Kies een van de volgende opties voor de mediation
:
mediation | Vergeleken met de Booleaanse vlag | Gedrag | |
---|---|---|---|
silent | Gelijk aan unmediated: true | Inloggegevens doorgegeven zonder dat er een accountkiezer wordt weergegeven. | |
optional | Gelijk aan unmediated: false | Toont een accountkiezer als preventSilentAccess() eerder is aangeroepen. | |
required | Een nieuwe optie | Toon altijd een accountkiezer. Handig als u een gebruiker wilt laten wisselen van account via het eigen accountkiezervenster. |
In dit voorbeeld wordt de referentie doorgegeven zonder dat er een accountkiezer wordt weergegeven, het equivalent van de vorige vlag, unmediated: true
:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
requireUserMediation()
hernoemd naar preventSilentAccess()
Om goed af te stemmen op de nieuwe mediation
die wordt aangeboden in de get()
-aanroep, is de naam navigator.credentials.requireUserMediation()
hernoemd naar navigator.credentials.preventSilentAccess()
.
De hernoemde methode voorkomt dat een inloggegevens worden doorgegeven zonder dat de accountkiezer wordt weergegeven (soms aangeroepen zonder tussenkomst van de gebruiker). Dit is handig wanneer een gebruiker zich afmeldt bij een website of zich afmeldt van een website en niet automatisch opnieuw wil inloggen bij het volgende bezoek.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
Credential-objecten asynchroon maken met de nieuwe methode navigator.credentials.create()
U hebt nu de mogelijkheid om referentieobjecten asynchroon te maken met de nieuwe methode navigator.credentials.create()
. Lees verder voor een vergelijking tussen zowel de synchronisatie- als de async-benadering.
Een PasswordCredential
object maken
Synchronisatie aanpak
let c = new PasswordCredential(form);
Asynchrone aanpak (nieuw)
let c = await navigator.credentials.create({
password: form
});
of:
let c = await navigator.credentials.create({
password: {
id: id,
password: password
}
});
Een FederatedCredential
object maken
Synchronisatie aanpak
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
Asynchrone aanpak (nieuw)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
}
});
Migratie gids
Heeft u een bestaande implementatie van de Credential Management API? We hebben een migratiehandleiding die u kunt volgen om te upgraden naar de nieuwe versie.