Alcuni degli aggiornamenti descritti qui sono spiegati nella sessione Google I/O, Secure and Rapid Sign-In: Keeping Users Engaged:
Chrome 57
Chrome 57 ha introdotto questa importante modifica all'API Credential Management.
Le credenziali possono essere condivise da un sottodominio diverso
Ora Chrome può recuperare una credenziale archiviata in un sottodominio diverso utilizzando l'API Credential Management.
Ad esempio, se una password è memorizzata in login.example.com
, uno script su www.example.com
può mostrarla come una delle voci dell'account nella finestra di dialogo del selettore account.
Devi memorizzare esplicitamente la password utilizzando navigator.credentials.store()
in modo che, quando un utente sceglie una credenziale toccando la finestra di dialogo, la password venga passata e copiata nell'origine attuale.
Una volta archiviata, la password sarà disponibile come credenziale nella stessa origine da www.example.com
in poi.
Nello screenshot seguente, le informazioni sulle credenziali archiviate in login.aliexpress.com
sono visibili a m.aliexpress.com
e possono essere scelte dall'utente:
Chrome 60
Chrome 60 introduce diverse modifiche importanti all'API Credential Management:
Poiché la funzione
fetch()
personalizzata non è più necessaria per recuperare la password, verrà deprecata a breve.navigator.credentials.get()
ora accetta un'enummediation
invece del flag booleanounmediated
.Il nuovo metodo
navigator.credentials.create()
crea in modo asincrono oggetti credenziali.
Il rilevamento delle funzionalità richiede attenzione
Per vedere se l'API Credential Management per l'accesso a credenziali basate su password e federate è disponibile, controlla se window.PasswordCredential
o window.FederatedCredential
sono disponibili.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
L'oggetto PasswordCredential
ora include la password
L'API Credential Management ha adottato un approccio conservativo per la gestione delle password.
Ha nascosto le password in JavaScript, richiedendo agli sviluppatori di inviare l'oggetto PasswordCredential
direttamente al proprio server per la convalida tramite un'estensione all'API fetch()
.
Tuttavia, questo approccio ha introdotto una serie di restrizioni. Abbiamo ricevuto feedback relativi all'impossibilità da parte degli sviluppatori di utilizzare l'API per i seguenti motivi:
Ha dovuto inviare la password come parte di un oggetto JSON.
Dovevano inviare il valore hash della password al proprio server.
Dopo aver eseguito un'analisi della sicurezza e aver compreso che nascondere le password da JavaScript non ha impedito a tutti i vettori di attacco con la stessa efficacia auspicata, abbiamo deciso di cambiare.
L'API Credential Management ora include una password non elaborata in un oggetto credenziali restituito, in modo da potervi accedere in testo normale. Puoi utilizzare i metodi esistenti per inviare informazioni sulle credenziali al server:
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);
});
Il recupero personalizzato verrà presto ritirato
Per determinare se stai utilizzando una funzione fetch()
personalizzata, controlla se utilizza un oggetto PasswordCredential
o un oggetto FederatedCredential
come valore della proprietà credentials
, ad esempio:
fetch('/signin', {
method: 'POST',
credentials: c
})
Si consiglia di utilizzare una funzione fetch()
normale come mostrato nell'esempio di codice precedente
o di utilizzare una funzione XMLHttpRequest
.
navigator.credentials.get()
ora accetta una mediazione enum
Fino a Chrome 60, navigator.credentials.get()
accettava una proprietà unmediated
facoltativa con un flag booleano. Ad esempio:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).then(c => {
// Sign-in
});
L'impostazione di unmediated: true
impedisce al browser di mostrare il selettore account durante il trasferimento di una credenziale.
Il flag è ora esteso come mediazione. La mediazione dell'utente può verificarsi nei seguenti casi:
Un utente deve scegliere un account con cui accedere.
Un utente vuole accedere esplicitamente dopo la chiamata
navigator.credentials.requireUseMediation()
.
Scegli una delle seguenti opzioni per il valore mediation
:
Valore mediation |
Rispetto al flag booleano | Comportamento | |
---|---|---|---|
silent |
È uguale a unmediated: true |
Credenziale passata senza mostrare un selettore account. | |
optional |
È uguale a unmediated: false |
Mostra un selettore account se
preventSilentAccess() ha chiamato in precedenza. |
|
required |
Una nuova opzione | Mostra sempre un selettore account. Utile quando vuoi consentire a un utente di cambiare account utilizzando la finestra di dialogo nativa del selettore account. |
In questo esempio, la credenziale viene passata senza mostrare un selettore account, l'equivalente del flag precedente unmediated: true
:
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
requireUserMediation()
rinominato in preventSilentAccess()
Per allinearsi correttamente con la nuova proprietà mediation
offerta nella chiamata get()
, il metodo navigator.credentials.requireUserMediation()
è stato rinominato in navigator.credentials.preventSilentAccess()
.
Il metodo rinominato impedisce di passare una credenziale senza mostrare il selettore account (a volte chiamato senza mediazione utente). Questo è utile quando un utente esce da un sito web o annulla la registrazione a un sito e non vuole accedere di nuovo automaticamente alla visita successiva.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
Crea oggetti credenziali in modo asincrono con il nuovo metodo navigator.credentials.create()
Ora hai la possibilità di creare oggetti credenziali in modo asincrono con il nuovo metodo, navigator.credentials.create()
.
Continua a leggere per un confronto tra l'approccio di sincronizzazione e quello asincrono.
Creazione di un oggetto PasswordCredential
in corso...
Approccio alla sincronizzazione
let c = new PasswordCredential(form);
Approccio asincrono (nuovo)
let c = await navigator.credentials.create({
password: form
});
oppure:
let c = await navigator.credentials.create({
password: {
id: id,
password: password
}
});
Creazione di un oggetto FederatedCredential
in corso...
Approccio alla sincronizzazione
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
Approccio asincrono (nuovo)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
}
});
Guida alla migrazione
Hai già un'implementazione dell'API Credential Management? Abbiamo un documento della guida alla migrazione che puoi seguire per eseguire l'upgrade alla nuova versione.