Einige der hier beschriebenen Aktualisierungen werden in der Google I/O-Sitzung Sichere und nahtlose Anmeldung: Nutzerinteraktionen beibehalten erläutert:
Chrome 57
Mit Chrome 57 wurde diese wichtige Änderung an der Credential Management API vorgenommen.
Anmeldedaten können von einer anderen Subdomain aus freigegeben werden
Chrome kann jetzt mithilfe der Credential Management API Anmeldedaten abrufen, die in einer anderen Subdomain gespeichert sind.
Wenn beispielsweise ein Passwort in login.example.com
gespeichert ist, kann ein Skript für www.example.com
es als eines der Kontoelemente im Dialogfeld zur Kontoauswahl anzeigen.
Du musst das Passwort explizit mit navigator.credentials.store()
speichern. Wenn ein Nutzer durch Tippen auf das Dialogfeld Anmeldedaten auswählt, wird das Passwort übergeben und in den aktuellen Ursprung kopiert.
Nach dem Speichern ist das Passwort abwärts als Anmeldedaten ab demselben 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 wurden mehrere wichtige Änderungen an der Credential Management API vorgenommen:
Da die benutzerdefinierte
fetch()
-Funktion zum Abrufen des Passworts nicht mehr erforderlich ist, wird sie bald eingestellt.navigator.credentials.get()
akzeptiert jetzt die Aufzählungmediation
anstelle des booleschen Flagsunmediated
.requireUserMediation()
wurde inpreventSilentAccess()
umbenannt.Mit der neuen Methode
navigator.credentials.create()
werden Anmeldedatenobjekte asynchron erstellt.
Für die Featureerkennung sind Maßnahmen 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 beim Umgang mit Passwörtern einen konservativen Ansatz.
Passwörter wurden vor JavaScript verborgen, sodass Entwickler das PasswordCredential
-Objekt zur Überprüfung über eine Erweiterung der fetch()
API direkt an ihren Server senden müssen.
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.
Nachdem wir eine Sicherheitsanalyse durchgeführt und erkannt hatten, dass das Verbergen von Passwörtern vor JavaScript nicht alle Angriffsvektoren so effektiv verhindert hat, wie wir gehofft hatten, haben wir uns dazu entschlossen, eine Änderung vorzunehmen.
Die Credential Management API enthält jetzt ein unformatiertes Passwort in ein zurückgegebenes Anmeldedatenobjekt, sodass Sie als Nur-Text darauf zugreifen können. Sie können die vorhandenen Methoden verwenden, um Anmeldedaten an Ihren Server zu senden:
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);
});
Benutzerdefinierter Abruf wird bald eingestellt
Wenn Sie ermitteln 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. Beispiel:
fetch('/signin', {
method: 'POST',
credentials: c
})
Es wird empfohlen, eine reguläre fetch()
-Funktion wie im vorherigen Codebeispiel zu verwenden oder eine XMLHttpRequest
zu verwenden.
navigator.credentials.get()
akzeptiert jetzt eine Vermittlung auf Aufzählungszeichen
Bis Chrome 60 hat navigator.credentials.get()
eine optionale unmediated
-Eigenschaft mit einem booleschen Flag akzeptiert. Beispiel:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).then(c => {
// Sign-in
});
Mit der Einstellung unmediated: true
wird verhindert, dass der Browser die Kontoauswahl anzeigt, wenn Anmeldedaten weitergegeben werden.
Das Flag wurde als Vermittlung erweitert. Die Vermittlung 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
navigator.credentials.requireUseMediation()
-Aufruf explizit anmelden.
Wählen Sie für den Wert mediation
eine der folgenden Optionen aus:
mediation Wert |
Im Vergleich zum booleschen Flag | Behavior | |
---|---|---|---|
silent |
Ist gleich unmediated: true |
Die Anmeldedaten wurden weitergegeben, ohne dass eine Kontoauswahl angezeigt wird. | |
optional |
Ist gleich unmediated: false |
Zeigt eine Kontoauswahl an, wenn preventSilentAccess() zuvor aufgerufen wurde. |
|
required |
Eine neue Option | Kontoauswahl immer anzeigen. Dies ist hilfreich, wenn Sie einem Nutzer ermöglichen möchten, ein Konto über das Dialogfeld zur Kontoauswahl zu wechseln. |
In diesem Beispiel werden die Anmeldedaten übergeben, ohne dass eine Kontoauswahl angezeigt wird. Dies entspricht dem vorherigen Flag unmediated: true
:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
requireUserMediation()
umbenannt in preventSilentAccess()
Die Methode navigator.credentials.requireUserMediation()
wurde in navigator.credentials.preventSilentAccess()
umbenannt, um sie gut an die neue Eigenschaft mediation
anzupassen, die im get()
-Aufruf angeboten wird.
Die umbenannte Methode verhindert, dass Anmeldedaten weitergegeben werden, ohne dass die Kontoauswahl angezeigt wird (manchmal ohne Nutzervermittlung aufgerufen). Das ist hilfreich, 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, Anmeldedatenobjekte asynchron mit der neuen Methode navigator.credentials.create()
zu erstellen.
Lesen Sie weiter, um einen Vergleich zwischen dem Synchronisierungs- und dem Asynchron-Ansatz zu vergleichen.
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: 'https://*****'
}
});
Migrationsanleitung
Sie haben bereits eine Implementierung der Credential Management API? Wir bieten Ihnen einen Migrationsleitfaden, den Sie für das Upgrade auf die neue Version befolgen können.