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 unter login.aliexpress.com
gespeicherte Anmeldedaten für m.aliexpress.com
sichtbar und stehen dem Nutzer zur Auswahl:
Chrome 60
Mit Chrome 60 werden mehrere wichtige Änderungen an der Credential Management API eingeführt:
Da die benutzerdefinierte Funktion
fetch()
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 hat Passwörter vor JavaScript verborgen, 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 wurde als Teil eines JSON-Objekts gesendet.
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);
});
Der benutzerdefinierte Abruf wird 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 Vermittlungsenumerierung
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 für die Anmeldung auswählen.
Ein Nutzer möchte sich nach dem
navigator.credentials.requireUseMediation()
-Aufruf 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 bestanden, ohne dass eine Kontoauswahl angezeigt wird. | |
optional |
Ist gleich unmediated: false |
Zeigt eine Kontoauswahl an, wenn preventSilentAccess() zuvor aufgerufen wurde. |
|
required |
Neue Option | Kontoauswahl immer anzeigen. Nützlich, wenn Sie Nutzern erlauben möchten, über das native Auswahlfenster für Konten 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
Um die neue mediation
-Eigenschaft im get()
-Aufruf besser zu unterstützen, wurde die Methode navigator.credentials.requireUserMediation()
in navigator.credentials.preventSilentAccess()
umbenannt.
Durch die umbenannte Methode werden Anmeldedaten nicht übergeben, ohne dass die Kontoauswahl angezeigt wird (manchmal ohne Nutzervermittlung aufgerufen). 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
Du hast die Credential Management API bereits implementiert? In unserem Migrationsleitfaden finden Sie eine Anleitung zum Upgrade auf die neue Version.