Semplificazione del flusso di accesso utilizzando l'API di gestione delle credenziali

Per offrire un'esperienza utente sofisticata, è importante aiutare gli utenti ad autenticarsi sul tuo sito web. Gli utenti autenticati possono interagire tra loro utilizzando un profilo dedicato, sincronizzare i dati tra dispositivi o elaborarli offline e l'elenco potrebbe continuare all'infinito. Tuttavia, creare, ricordare e digitare password tende a essere complicato per gli utenti finali, soprattutto su schermi di dispositivi mobili, il che li porta a riutilizzare le stesse password su siti diversi. Ciò rappresenta ovviamente un rischio per la sicurezza.

La versione più recente di Chrome (51) supporta l'API Credential Management. Si tratta di una proposta di standard del W3C che offre agli sviluppatori accesso programmatico al gestore delle credenziali di un browser e aiuta gli utenti ad accedere più facilmente.

Che cos'è l'API Credential Management?

L'API Credential Management consente agli sviluppatori di archiviare e recuperare le credenziali con password e le credenziali federate e offre tre funzioni:

  • navigator.credentials.get()
  • navigator.credentials.store()
  • navigator.credentials.requireUserMediation()

Utilizzando queste API semplici, gli sviluppatori possono eseguire operazioni efficaci come:

  • Consenti agli utenti di accedere con un solo tocco.
  • Ricorda l'account federato utilizzato dall'utente per accedere.
  • Chiedi agli utenti di accedere di nuovo quando una sessione scade.

Nell'implementazione di Chrome, le credenziali verranno memorizzate nel Gestore delle password di Chrome. Se gli utenti hanno eseguito l'accesso a Chrome, possono sincronizzare le password su più dispositivi. Queste password sincronizzate possono essere condivise anche con le app per Android che hanno integrato l'API Smart Lock per password per Android per un'esperienza multipiattaforma senza interruzioni.

Integrare l'API Credential Management con il tuo sito

Il modo in cui utilizzi l'API Credential Management con il tuo sito web può variare in base alla sua architettura. Si tratta di un'app a pagina singola? Si tratta di un'architettura legacy con transizioni di pagina? Il modulo di accesso si trova solo nella pagina superiore? I pulsanti di accesso sono presenti ovunque? Gli utenti possono navigare in modo significativo sul tuo sito web senza accedere? La federazione funziona nelle finestre popup? Oppure richiede l'interazione su più pagine?

È quasi impossibile coprire tutti questi casi, ma diamo un'occhiata a una tipica app a pagina singola.

  • La pagina superiore è un modulo di registrazione.
  • Se toccano il pulsante "Accedi", gli utenti vengono indirizzati a un modulo di accesso.
  • Sia i moduli di registrazione che quelli di accesso dispongono delle opzioni di credenziali identificative/password e di federazione, ad esempio con Accedi con Google e Accedi con Facebook.

Utilizzando l'API Credential Management, potrai aggiungere al sito le seguenti funzionalità, ad esempio:

  • Mostra un selettore di account al momento dell'accesso: viene visualizzata un'interfaccia utente del selettore di account nativo quando un utente tocca "Accedi".
  • Salva le credenziali:dopo aver eseguito l'accesso correttamente, offri la possibilità di salvare le informazioni sulle credenziali nel gestore delle password del browser per utilizzarle in un secondo momento.
  • Consenti all'utente di accedere di nuovo automaticamente:consenti all'utente di accedere di nuovo se una sessione è scaduta.
  • Media l'accesso automatico:dopo che un utente è uscito, disattiva l'accesso automatico per la sua visita successiva.

Puoi provare queste funzionalità implementate in un sito demo con il relativo codice di esempio.

Mostrare il selettore di account durante l'accesso

Tra il tocco di un pulsante "Accedi" da parte dell'utente e il passaggio a un modulo di accesso, puoi utilizzare navigator.credentials.get() per ottenere le informazioni sulle credenziali. Chrome mostrerà un'interfaccia utente di scelta dell'account da cui l'utente può scegliere un account.

Viene visualizzata un'interfaccia utente di selezione dell'account per consentire all'utente di selezionare un account per accedere.
Viene visualizzata un'interfaccia utente del selettore di account per consentire all'utente di selezionare un account per accedere

Ottenere un oggetto credenziale password

Per mostrare le credenziali della password come opzioni dell'account, utilizza password: true.

navigator.credentials.get({
    password: true, // `true` to obtain password credentials
}).then(function(cred) {
    // continuation
    ...

Utilizzo di una credenziale con password per accedere

Una volta che l'utente ha selezionato un account, la funzione di risoluzione riceve una credenza della password. Puoi inviarlo al server utilizzando fetch():

    // continued from previous example
}).then(function(cred) {
    if (cred) {
    if (cred.type == 'password') {
        // Construct FormData object
        var form = new FormData();

        // Append CSRF Token
        var csrf_token = document.querySelector('csrf_token').value;
        form.append('csrf_token', csrf_token);

        // You can append additional credential data to `.additionalData`
        cred.additionalData = form;

        // `POST` the credential object as `credentials`.
        // id, password and the additional data will be encoded and
        // sent to the url as the HTTP body.
        fetch(url, {           // Make sure the URL is HTTPS
        method: 'POST',      // Use POST
        credentials: cred    // Add the password credential object
        }).then(function() {
        // continuation
        });
    } else if (cred.type == 'federated') {
        // continuation

Utilizzo di una credenziale federata per accedere

Per mostrare gli account federati a un utente, aggiungi federated, che accetta un array di fornitori di identità, alle opzioni get().

Quando nel Gestore delle password sono memorizzati più account.
Quando nel Gestore delle password sono memorizzati più account
navigator.credentials.get({
    password: true, // `true` to obtain password credentials
    federated: {
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    }
}).then(function(cred) {
    // continuation
    ...

Puoi esaminare la proprietà type dell'oggetto credenziale per verificare se è PasswordCredential (type == 'password') o FederatedCredential (type == 'federated'). Se la credenziale è un FederatedCredential, puoi chiamare l'API appropriata utilizzando le informazioni in essa contenute.

    });
} else if (cred.type == 'federated') {
    // `provider` contains the identity provider string
    switch (cred.provider) {
    case 'https://accounts.google.com':
        // Federated login using Google Sign-In
        var auth2 = gapi.auth2.getAuthInstance();

        // In Google Sign-In library, you can specify an account.
        // Attempt to sign in with by using `login_hint`.
        return auth2.signIn({
        login_hint: cred.id || ''
        }).then(function(profile) {
        // continuation
        });
        break;

    case 'https://www.facebook.com':
        // Federated login using Facebook Login
        // continuation
        break;

    default:
        // show form
        break;
    }
}
// if the credential is `undefined`
} else {
// show form
Diagramma di flusso per la gestione delle credenziali.

Memorizzare le credenziali

Quando un utente accede al tuo sito web utilizzando un modulo, puoi utilizzare navigator.credentials.store() per memorizzare la credenziale. All'utente verrà chiesto se salvarlo o meno. A seconda del tipo di credenziale, utilizza new PasswordCredential() o new FederatedCredential() per creare un oggetto credenziali da memorizzare.

Chrome chiede agli utenti se vogliono memorizzare le credenziali (o un provider di federazione).
Chrome chiede agli utenti se vogliono memorizzare le credenziali (o un provider di federazione)

Creazione e memorizzazione di una credenziale di password da un elemento del modulo

Il seguente codice utilizza gli attributi autocomplete per mappare automaticamente gli elementi del modulo ai parametri dell'oggetto PasswordCredential.

HTML html <form id="form" method="post"> <input type="text" name="id" autocomplete="username" /> <input type="password" name="password" autocomplete="current-password" /> <input type="hidden" name="csrf_token" value="******" /> </form>

JavaScript

var form = document.querySelector('\#form');
var cred = new PasswordCredential(form);
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});

Creazione e archiviazione di una credenziale federata

// After a federation, create a FederatedCredential object using
// information you have obtained
var cred = new FederatedCredential({
    id: id,                                  // The id for the user
    name: name,                              // Optional user name
    provider: 'https://accounts.google.com',  // A string that represents the identity provider
    iconURL: iconUrl                         // Optional user avatar image url
});
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});
Diagramma di flusso di accesso.

Consentire all'utente di accedere di nuovo automaticamente

Quando un utente esce dal tuo sito web e torna più tardi, è possibile che la sessione sia scaduta. Non chiedere all'utente di digitare la password ogni volta che ritorna. Consenti all'utente di accedere di nuovo automaticamente.

Quando un utente accede automaticamente, viene visualizzata una notifica.
Quando un utente accede automaticamente, viene visualizzata una notifica.

Ottenere un oggetto credenziali

navigator.credentials.get({
    password: true, // Obtain password credentials or not
    federated: {    // Obtain federation credentials or not
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    },
    unmediated: true // `unmediated: true` lets the user automatically sign in
}).then(function(cred) {
    if (cred) {
    // auto sign-in possible
    ...
    } else {
    // auto sign-in not possible
    ...
    }
});

Il codice dovrebbe essere simile a quello visualizzato nella sezione "Mostra selettore account al momento dell'accesso". L'unica differenza è che imposterai unmediated: true.

In questo modo la funzione viene risolta immediatamente e ti fornisce le credenziali per far accedere automaticamente l'utente. Esistono alcune condizioni:

  • L'utente ha confermato la funzionalità di accesso automatico in un messaggio di benvenuto.
  • L'utente ha già eseguito l'accesso al sito web utilizzando l'API Credential Management.
  • L'utente ha una sola credenziale memorizzata per la tua origine.
  • L'utente non si è disconnesso esplicitamente nella sessione precedente.

Se una di queste condizioni non viene soddisfatta, la funzione viene rifiutata.

Diagramma di flusso dell&#39;oggetto credenziali

Mediare l'accesso automatico

Quando un utente esce dal tuo sito web, è tua responsabilità assicurarti che non esegua nuovamente l'accesso automaticamente. Per garantire questo, l'API Credential Management fornisce un meccanismo chiamato mediazione. Puoi attivare la modalità di mediazione chiamando navigator.credentials.requireUserMediation(). Se lo stato della mediazione dell'utente per l'origine è attivo, l'utilizzo di unmediated: true con navigator.credentials.get() risolverà la funzione con undefined.

Mediazione dell'accesso automatico

navigator.credentials.requireUserMediation();
Diagramma di flusso dell&#39;accesso automatico.

Domande frequenti

È possibile che JavaScript sul sito web recuperi una password non elaborata? No. Puoi ottenere le password solo nell'ambito di PasswordCredential e non sono esposte in alcun modo.

È possibile memorizzare 3 serie di cifre per un ID utilizzando l'API Credential Management? Al momento no. Il tuo feedback sulla specifica sarà molto apprezzato.

Posso utilizzare l'API Credential Management all'interno di un iframe? L'API è limitata ai contesti di primo livello. Le chiamate a .get() o .store() in un iframe verranno risolte immediatamente senza effetto.

Posso integrare la mia estensione di Chrome per la gestione delle password con l'API Credential Management? Puoi eseguire l'override di navigator.credentials e collegarlo all'estensione di Chrome per le credenziali get() o store().

Risorse

Per scoprire di più sull'API Credential Management, consulta la Guida all'integrazione.