Alcuni degli aggiornamenti descritti qui sono spiegati nella sessione Google I/O, Accesso sicuro e senza interruzioni per mantenere alto il coinvolgimento degli utenti:
Chrome 57
Chrome 57 ha introdotto questa importante modifica API Credential Management.
Le credenziali possono essere condivise da un sottodominio diverso
Ora Chrome può recuperare una credenziale memorizzata in un sottodominio diverso utilizzando
API Credential Management.
Ad esempio, se una password è memorizzata in login.example.com
,
uno script su www.example.com
può mostrarlo come uno degli elementi dell'account nella finestra di dialogo del selettore account.
Devi archiviare esplicitamente la password utilizzando navigator.credentials.store()
,
in modo che quando un utente sceglie una credenziale toccando la finestra di dialogo
la password viene passata e copiata nell'origine attuale.
Una volta archiviata, la password è disponibile come credenziale
esattamente nella stessa origine dal giorno www.example.com
in poi.
Nello screenshot seguente, le informazioni sulle credenziali memorizzate in login.aliexpress.com
è visibile a m.aliexpress.com
e può essere scelto dall'utente:
Chrome 60
Chrome 60 introduce diverse modifiche importanti API Credential Management:
Poiché la funzione
fetch()
personalizzata non è più necessaria per recuperare la password, presto sarà deprecato.navigator.credentials.get()
ora accetta un'enumerazionemediation
invece del flag booleanounmediated
.requireUserMediation()
è stato rinominatopreventSilentAccess()
.Nuovo metodo
navigator.credentials.create()
crea oggetti delle credenziali in modo asincrono.
Il rilevamento delle caratteristiche richiede attenzione
Per vedere se l'API Credential Management per accedere a servizi basati su password e
credenziali federate disponibili, controlla se window.PasswordCredential
o
window.FederatedCredential
è disponibile.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
PasswordCredential
oggetto ora include la password
L'API Credential Management ha adottato un approccio conservativo alla gestione delle password.
Ha nascosto le password da JavaScript, richiedendo agli sviluppatori
per inviare l'oggetto PasswordCredential
direttamente al server
per la convalida tramite un'estensione dell'API fetch()
.
Tuttavia, questo approccio ha introdotto una serie di restrizioni. Abbiamo ricevuto feedback secondo cui gli sviluppatori non potevano utilizzare l'API perché:
Ha dovuto inviare la password come parte di un oggetto JSON.
Dovevano inviare il valore hash della password al loro server.
Dopo aver eseguito un'analisi della sicurezza e aver riconosciuto che le password da JavaScript non ha impedito tutti i vettori di attacco nell'efficacia che speravamo, abbiamo deciso di cambiare.
L'API Credential Management ora include una password non elaborata in un oggetto credenziali restituito, in modo che sia possibile accedervi come testo normale. Puoi utilizzare i metodi esistenti per fornire informazioni sulle credenziali al tuo 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à ritirato a breve
Per determinare se stai utilizzando una funzione fetch()
personalizzata:
verifica se utilizza un oggetto PasswordCredential
o FederatedCredential
come valore della proprietà credentials
, ad esempio:
fetch('/signin', {
method: 'POST',
credentials: c
})
Utilizzando una normale funzione fetch()
come mostrato nell'esempio di codice precedente,
o l'utilizzo di XMLHttpRequest
.
navigator.credentials.get()
ora accetta una mediazione enum
Fino a Chrome 60,
navigator.credentials.get()
ha accettato 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.
quando passi una credenziale.
Il flag è ora esteso come mediazione. La mediazione degli utenti può avvenire nei seguenti casi:
Un utente deve scegliere un account con cui accedere.
Un utente vuole accedere esplicitamente dopo la chiamata di
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 trasmessa 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 se vuoi consentire a un utente di cambiare account utilizzando la finestra di dialogo di selezione account nativa. |
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 allinearti perfettamente alla nuova proprietà mediation
offerta nella chiamata get()
,
il metodo navigator.credentials.requireUserMediation()
è stato rinominato
navigator.credentials.preventSilentAccess()
.
Il metodo rinominato impedisce di passare una credenziale senza mostrare il Selettore account (talvolta chiamata senza mediazione dell'utente). È utile quando un utente esce da un sito web o annulla la registrazione da uno di questi 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 sincronizzazione e l'approccio 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? È disponibile un documento di guida alla migrazione puoi seguire l'upgrade alla nuova versione.