Einige der hier beschriebenen Änderungen werden in der Google I/O-Sitzung Secure and Seamless Sign-In: Keeping Users Engaged (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 über eine andere Subdomain 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 es in einem Script auf login.example.com
im Dialogfeld für die Kontoauswahl als eines der Kontoelemente angezeigt werden.www.example.com
Sie müssen das Passwort explizit mit navigator.credentials.store()
speichern, damit das Passwort übergeben und in den aktuellen Ursprung kopiert wird, wenn ein Nutzer durch Tippen auf das Dialogfeld Anmeldedaten auswählt.
Nach dem Speichern ist das Passwort ab www.example.com
als Anmeldedaten an genau derselben Quelle verfügbar.
Im folgenden Screenshot sind die Anmeldedaten, die unter login.aliexpress.com
gespeichert sind, für m.aliexpress.com
sichtbar und können vom Nutzer ausgewählt werden:
Chrome 60
Mit Chrome 60 werden mehrere wichtige Änderungen an der Credential Management API eingeführt:
Da die benutzerdefinierte
fetch()
-Funktion zum Abrufen des Passworts nicht mehr erforderlich ist, wird sie bald eingestellt.navigator.credentials.get()
akzeptiert jetzt ein Enummediation
anstelle des booleschen Flagsunmediated
.requireUserMediation()
wurde inpreventSilentAccess()
umbenannt.Mit der neuen Methode
navigator.credentials.create()
werden Anmeldedatenobjekte asynchron erstellt.
Funktionserkennung erfordert Aufmerksamkeit
Ob die Credential Management API für den Zugriff auf passwortbasierte und föderierte Anmeldedaten verfügbar ist, erkennen Sie daran, ob window.PasswordCredential
oder window.FederatedCredential
verfügbar ist.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
Das PasswordCredential
-Objekt enthält jetzt das Passwort
Bei der Credential Management API wurde ein konservativer Ansatz für die Passwortverwaltung gewählt.
Sie verborgen Passwörter vor JavaScript, sodass Entwickler das PasswordCredential
-Objekt zur Validierung über eine Erweiterung der fetch()
API direkt an ihren Server senden mussten.
Dieser Ansatz führte jedoch zu einer Reihe von Einschränkungen. Wir haben Feedback erhalten, dass Entwickler die API nicht verwenden konnten, weil:
Das Passwort musste als Teil eines JSON-Objekts gesendet werden.
Sie mussten den Hashwert des Passworts an ihren Server senden.
Nach einer Sicherheitsanalyse haben wir festgestellt, dass das Verstecken von Passwörtern vor JavaScript nicht alle Angriffsvektoren so effektiv verhindert, wie wir gehofft hatten. Deshalb haben wir uns entschlossen, eine Änderung vorzunehmen.
Die Credential Management API enthält jetzt ein Rohpasswort in einem zurückgegebenen Anmeldedatenobjekt, sodass Sie darauf als Klartext 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'
}).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);
});
Benutzerdefinierte Abrufe werden bald eingestellt
Ob Sie eine benutzerdefinierte fetch()
-Funktion verwenden, erkennen Sie daran, ob ein PasswordCredential
-Objekt oder ein FederatedCredential
-Objekt als Wert der credentials
-Property verwendet wird, z. B.:
fetch('/signin', {
method: 'POST',
credentials: c
})
Es wird empfohlen, eine reguläre fetch()
-Funktion wie im vorherigen Codebeispiel gezeigt oder eine XMLHttpRequest
zu verwenden.
navigator.credentials.get()
akzeptiert jetzt eine enum-Vermittlung
Bis Chrome 60 wurde für 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
});
Wenn Sie unmediated: true
festlegen, wird die Kontoauswahl nicht angezeigt, wenn Anmeldedaten übergeben werden.
Das Flag wird jetzt als Vermittlung erweitert. Die Nutzervermittlung 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()
-Anruf explizit anmelden.
Wählen Sie einen der folgenden Werte für mediation
aus:
mediation Wert |
Im Vergleich zu einem booleschen Flag | Verhalten | |
---|---|---|---|
silent |
Ist gleich unmediated: true |
Anmeldedaten wurden übergeben, ohne dass eine Kontoauswahl angezeigt wurde. | |
optional |
Ist gleich unmediated: false |
Zeigt eine Kontoauswahl an, wenn preventSilentAccess() zuvor aufgerufen wurde. |
|
required |
Eine neue Option | Eine Kontoauswahl immer anzeigen. Nützlich, wenn Sie Nutzern erlauben möchten, über das native Dialogfeld für die Kontoauswahl das Konto zu wechseln. |
In diesem Beispiel werden die Anmeldedaten übergeben, ohne dass eine Kontoauswahl angezeigt wird. Das entspricht dem vorherigen Flag unmediated: true
:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
requireUserMediation()
in preventSilentAccess()
umbenannt
Die Methode navigator.credentials.requireUserMediation()
wurde in navigator.credentials.preventSilentAccess()
umbenannt, um sie besser an die neue mediation
-Eigenschaft anzupassen, die im get()
-Aufruf angeboten wird.
Mit der umbenannten Methode wird verhindert, dass Anmeldedaten übergeben werden, ohne dass die Kontoauswahl angezeigt wird (manchmal auch als „ohne Nutzervermittlung“ bezeichnet). Das ist nützlich, wenn sich ein Nutzer von einer Website abmeldet oder sich dort abmeldet und nicht beim nächsten Besuch automatisch wieder angemeldet werden möchte.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
Anmeldedatenobjekte asynchron mit der neuen Methode navigator.credentials.create()
erstellen
Mit der neuen Methode navigator.credentials.create()
können Sie jetzt asynchron Anmeldedatenobjekte 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: 'https://*****'
}
});
Migrationsanleitung
Haben Sie bereits eine Implementierung der Credential Management API? In unserem Migrationsleitfaden finden Sie eine Anleitung zum Upgrade auf die neue Version.