Einige der hier beschriebenen Updates werden in der Google I/O-Sitzung Sichere und nahtlose Anmeldung: Nutzer binden erläutert:
Chrome 57
In Chrome 57 wurde diese wichtige Änderung an der Credential Management API eingeführt.
Anmeldedaten können von einer anderen Subdomain freigegeben werden
Chrome kann jetzt mit der Credential Management API in einer anderen Subdomain gespeicherte Anmeldedaten abrufen.
Wenn ein Passwort beispielsweise in login.example.com gespeichert ist, kann es von einem Script auf www.example.com als eines der Kontoelemente im Dialogfeld zur Kontoauswahl angezeigt werden.
Sie müssen das Passwort explizit mit navigator.credentials.store() speichern, damit das Passwort beim Auswählen von Anmeldedaten durch Tippen auf das Dialogfeld an den aktuellen Ursprung übergeben und dorthin kopiert wird.
Nach dem Speichern ist das Passwort als Anmeldedaten im exakt selben Ursprung www.example.com verfügbar.
Im folgenden Screenshot sind die unter login.aliexpress.com gespeicherten Anmeldedaten für m.aliexpress.com sichtbar und können vom Nutzer ausgewählt werden:
Chrome 60
In Chrome 60 werden mehrere wichtige Änderungen an der Credential Management API eingeführt:
Da die benutzerdefinierte
fetch()-Funktion nicht mehr zum Abrufen des Passworts erforderlich ist, wird sie bald eingestellt.navigator.credentials.get()akzeptiert jetzt ein Enummediationanstelle des booleschen Flagsunmediated.requireUserMediation()wurde inpreventSilentAccess()umbenannt.Die neue Methode
navigator.credentials.create()erstellt asynchron Anmeldedatenobjekte.
Maßnahme für die Funktionserkennung erforderlich
Wenn Sie wissen möchten, ob die Credential Management API für den Zugriff auf passwortbasierte und föderierte Anmeldedaten verfügbar ist, prüfen Sie, ob window.PasswordCredential oder window.FederatedCredential verfügbar ist.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
PasswordCredential-Objekt enthält jetzt ein Passwort
Die Credential Management API verfolgte einen konservativen Ansatz für den Umgang mit Passwörtern.
Passwörter wurden vor JavaScript verborgen. Entwickler mussten das PasswordCredential-Objekt direkt an ihren Server senden, um es über eine Erweiterung der fetch() API zu validieren.
Dieser Ansatz brachte jedoch eine Reihe von Einschränkungen mit sich. Wir haben Feedback erhalten, dass Entwickler die API aus folgenden Gründen nicht verwenden konnten:
Sie mussten das Passwort als Teil eines JSON-Objekts senden.
Sie mussten den Hashwert des Passworts an ihren Server senden.
Nach einer Sicherheitsanalyse haben wir festgestellt, dass das Verbergen von Passwörtern vor JavaScript nicht alle Angriffsvektoren so effektiv verhindert, wie wir gehofft hatten. Deshalb haben wir uns entschieden, eine Änderung vorzunehmen.
Die Credential Management API enthält jetzt ein Rohpasswort in einem zurückgegebenen Anmeldedatenobjekt, sodass Sie als Nur-Text darauf zugreifen können. Sie können vorhandene Methoden verwenden, um Anmeldedaten an Ihren Server zu senden:
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);
});
Benutzerdefinierter Abruf wird bald eingestellt
Wenn Sie herausfinden möchten, ob Sie eine benutzerdefinierte fetch()-Funktion verwenden, prüfen Sie, ob sie ein PasswordCredential-Objekt oder ein FederatedCredential-Objekt als Wert des Attributs credentials verwendet, z. B.:
fetch('/signin', {
method: 'POST',
credentials: c
})
Es wird empfohlen, eine reguläre fetch()-Funktion wie im vorherigen Codebeispiel oder eine XMLHttpRequest zu verwenden.
navigator.credentials.get() akzeptiert jetzt eine Enum-Mediation.
Bis Chrome 60 akzeptierte navigator.credentials.get() ein optionales unmediated-Attribut mit einem booleschen Flag. Beispiel:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).>then(c = {
// Sign-in
});
Wenn Sie unmediated: true festlegen, wird verhindert, dass der Browser die Kontoauswahl anzeigt, wenn Anmeldedaten übergeben werden.
Das Flag wird jetzt als Vermittlung erweitert. Die Nutzermediation kann in folgenden Fällen erfolgen:
Ein Nutzer muss ein Konto auswählen, mit dem er sich anmelden möchte.
Ein Nutzer möchte sich nach dem Aufruf von
navigator.credentials.requireUseMediation()explizit anmelden.
Wählen Sie eine der folgenden Optionen für den Wert mediation aus:
mediation Wert |
Im Vergleich zum booleschen Flag | Verhalten | |
|---|---|---|---|
silent |
Gleich unmediated: true |
Anmeldedaten wurden ohne Anzeige einer Kontoauswahl übergeben. | |
optional |
Gleich unmediated: false |
Zeigt eine Kontoauswahl an, wenn zuvor preventSilentAccess() aufgerufen wurde. |
|
required |
Eine neue Option | Immer eine Kontoauswahl anzeigen. Nützlich, wenn du einem Nutzer die Möglichkeit geben möchtest, das Konto über das native Kontoauswahldialogfeld zu wechseln. |
In diesem Beispiel werden die Anmeldedaten ohne Anzeige einer Kontoauswahl übergeben, was dem vorherigen Flag unmediated: true entspricht:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent&>#39;
}).then(c = {
// Sign-in
});
requireUserMediation() wurde in preventSilentAccess() umbenannt
Damit die Methode navigator.credentials.requireUserMediation() gut zum neuen Attribut mediation passt, das im Aufruf get() angeboten wird, wurde sie in navigator.credentials.preventSilentAccess() umbenannt.
Die umbenannte Methode verhindert, dass Anmeldedaten ohne Anzeige der Kontoauswahl übergeben werden (manchmal auch als „ohne Nutzermediation“ bezeichnet). Das ist nützlich, wenn sich ein Nutzer von einer Website abmeldet oder sich von einer Website abmeldet und beim nächsten Besuch nicht automatisch wieder angemeldet werden möchte.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
Anmeldedatenobjekte asynchron mit der neuen Methode navigator.credentials.create() erstellen
Sie haben jetzt die Möglichkeit, mit der neuen Methode navigator.credentials.create() asynchron Anmeldedatenobjekte zu erstellen.
Im Folgenden finden Sie einen Vergleich zwischen dem synchronen und dem asynchronen Ansatz.
PasswordCredential-Objekt erstellen
Synchronisierungsansatz
let c = new PasswordCredential(form);
Asynchroner Ansatz (neu)
let c = await navigator.credentials.create({
password: form
});
oder
let c = await navigator.credentials.create({
password: {
id: id,
password: password
}
});
FederatedCredential-Objekt erstellen
Synchronisierungsansatz
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
Asynchroner Ansatz (neu)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 39;https://*****'
}
});
Migrationsanleitung
Haben Sie bereits eine Implementierung der Credential Management API? Wir haben eine Migrationsanleitung, der Sie folgen können, um ein Upgrade auf die neue Version durchzuführen.