Aggiungere Utenti

6

Percentuale Tradotta

In questo capitolo imparerai:

  • Come utilizzare gli account utente in Meteor.
  • Come abilitare l'autenticazione in Microscope.
  • Utilizzare il package accounts-ui per implementare l'interfaccia utente.
  • Finora si è lavorato alla creazione e visualizzazione di dati di esempio statici ed implementato un semplice prototipo.

    È stato verificato come l'interfaccia utente sia reattiva a variazioni dei dati, con inserimenti e modifiche che vengono presentati immediatamente. Tuttavia, il sito è ancora penalizzato dal fatto che non è possibile inserire dati. E infatti ancora non vengono neanche gestiti gli utenti.

    Vediamo come sia possibile sistemare la cosa.

    Account: gestire utenti in modo semplice

    In molti framework per il web, aggiungere profili utente è un problema ricorrente. Quasi ogni progetto necessita di profili utente, e purtroppo spesso è più complicato di quanto invece dovrebbe e potrebbe essere. Inoltre, non appena si renda necessario interagire con OAuth o altri schemi di autenticazione di terze parti, le cose tendono a complicarsi ulteriormente.

    Fortunatamente, Meteor ha la soluzione. Grazie alla peculiarità dei package di Meteor di fornire codice sia lato server (JavaScript) che lato client (JavaScript, HTML e CSS), è possibile implementare un sistema di gestione degli account a costo quasi nullo.

    È sufficiente utilizzare l'interfaccia utente per gli account integrata in Meteor (tramite mrt add accounts-ui), ma poiché l'intera applicazione utilizza Bootstrap, verrà invece utilizzato il package accounts-ui-bootstrap-dropdown (niente di cui preoccuparsi, la sola differenza riguarda il foglio di stile). Da linea di comando, scrivere:

    $ mrt add accounts-ui-bootstrap-dropdown
    $ mrt add accounts-password
    
    Terminale

    Questi due comandi provvedono ad installare gli appositi template per gli account; è possibile includerli nel sito utilizzando {{> loginButtons}}. Un consiglio molto utile: si può controllare su quale lato posizionare il menù a tendina utilizzando l'attributo align (ad esempio: {{>loginButtons align="right"}}).

    È tempo di aggiungere i pulsanti all'header. Poiché l'header comincia a crescere oltremodo, è meglio concedergli un pò più di spazio spostandolo su un apposito template (che verrà salvato in client/views/includes/). Verrà anche utilizzato del markup aggiuntivo e alcune classi Bootstrap per migliorarlo dal punto di vista estetico:

    <template name="layout">
      <div class="container">
        {{> header}}
        <div id="main" class="row-fluid">
          {{> yield}}
        </div>
      </div>
    </template>
    
    client/views/application/layout.html
    <template name="header">
      <header class="navbar">
        <div class="navbar-inner">
          <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </a>
          <a class="brand" href="{{pathFor 'postsList'}}">Microscope</a>
          <div class="nav-collapse collapse">
            <ul class="nav pull-right">
              <li>{{> loginButtons}}</li>
            </ul>
          </div>
        </div>
      </header>
    </template>
    
    client/views/includes/header.html

    Ora, accedendo all'applicazione, i pulsanti per l'autenticazione saranno visualizzati nell'angolo in alto a destra del sito.

    Interfaccia utente per la gestione degli account integrata in Meteor
    Interfaccia utente per la gestione degli account integrata in Meteor

    È possibile utilizzarli per la registrazione, il login, per modificare la password, e tutto ciò che un semplice sito necessita per gli account basati su password.

    Per abilitare l'autenticazione tramite nome utente nel sistema di gestione degli account, è sufficiente aggiungere un blocco di configurazione Accounts.ui in un nuovo file config.js, da salvare in client/helpers/:

    Accounts.ui.config({
      passwordSignupFields: 'USERNAME_ONLY'
    });
    
    client/helpers/config.js

    Commit 6-1

    Added accounts and added template to the header

    Creazione del primo utente

    Procedendo e creando un nuovo account, il pulsante di registrazione “Sign in” cambierà per visualizzare il nome utente prescelto. Ciò conferma che un account utente è stato creato. Ma da dove provengono i dati relativi all'account utente?

    Con l'aggiunta del package accounts, Meteor ha creato una nuova collezione speciale, alla quale si può accedere come Meteor.users. Per consultarne il contenuto, aprire la console del browser e digitare:

     Meteor.users.findOne();
    
    Console del browser

    La console dovrebbe restituire un oggetto che rappresenta l'utente sopra creato; ad una osservazione più attenta si nota che il nome utente è incluso, così come un campo _id che identifica in maniera univoca l'utente. Da notare che è possibile ottenere l'utente correntemente autenticato tramite Meteor.user().

    Provando adesso ad uscire e registrandosi con un nuovo nome utente, Meteor.user() dovrebbe restituire il secondo utente. Tuttavia, se si prova ad eseguire:

     Meteor.users.find().count();
    1
    
    Console del browser

    La console restituisce 1. Non dovrebbe invece essere 2? È stato eliminato il primo utente? Provando a loggarsi utilizzando il primo account, si verifica immediatamente che non è questo il caso.

    È meglio assicurarsi controllando l'archivio dati predefinito, il database Mongo. Loggarsi in Mongo (meteor mongo da terminale) e verificare quanto segue:

    > db.users.count()
    2
    
    Console di Mongo

    Indubbiamente ci sono due utenti. Quindi perché solo uno per volta è visibile dal browser?

    Una pubblicazione misteriosa!

    Nel capitolo 4 si era parlato di come, disabilitando l’autopublishing, le collezioni non vengano più trasferite in maniera automatica dal server alla corrispondente versione locale della collezione, per ciascuno dei client collegati. Si è reso necessario create una coppia pubblicazione e sottoscrizione per veicolare i dati tra le parti.

    Ma non è stata mai creata una pubblicazione per gli utenti. Per cui, come è possibile che i dati utente siano visibili?

    La risposta sta nel fatto che il package degli account automaticamente esegue una “auto-pubblicazione” di un sottoinsieme dei dati relativi all'account dell'utente correntemente loggato. Se così non fosse, l'utente non sarebbe mai in grado di loggarsi sul sito!

    Comunque il package degli account pubblica solamente l'utente corrente. Questo spiega il perché i dati degli altri utenti non sono visibili.

    Quindi la pubblicazione è limitata ad un solo oggetto per utente loggato (e nessuno nel caso in cui non si è loggati).

    Inoltre, i documenti nella collezione degli utenti non contengono gli stessi campi tra server e client. In Mongo, un documento utente è composto da svariati campi. Per verificare, è sufficiente digitare dal terminale Mongo:

    > db.users.findOne()
    {
        "createdAt" : 1365649830922,
        "_id" : "kYdBd9hr3fWPGPcii",
        "services" : {
            "password" : {
                "srp" : {
                    "identity" : "qyFCnw4MmRbmGyBdN",
                    "salt" : "YcBjRa7ArXn5tdCdE",
                    "verifier" : "df2c001edadf4e475e703fa8cd093abd4b63afccbca48fad1d2a0986ff2bcfba920d3f122d358c4af0c287f8eaf9690a2c7e376d701ab2fe1acd53a5bc3e843905d5dcaf2f1c47c25bf5dd87764d1f58c8c01e4539872a9765d2b27c700dcdedadf5ac82521467356d3f91dbeaf9848158987c6d359c5423e6b9cabf34fa0b45"
                }
            },
            "resume" : {
                "loginTokens" : [
                    {
                        "token" : "BMHipQqjfLoPz7gru",
                        "when" : 1365649830922
                    }
                ]
            }
        },
        "username" : "tmeasday"
    }
    
    Console di Mongo

    Al lato opposto, nel browser l'oggetto utente è molto più scarno, come è possibile verificare digitando il comando equivalente:

     Meteor.users.findOne();
    Object {_id: "kYdBd9hr3fWPGPcii", username: "tmeasday"}
    
    Console del browser

    Questo esempio evidenzia come una collezione locale possa essere, per ragioni di sicurezza, un sottoinsieme dei dati presenti lato server. L'utente correntemente loggato accede solo al minimo indispensabile per un preciso scopo (nel caso in questione, l'autenticazione). Questo è uno schema ricorrente da tenere in considerazione, come si vedrà in seguito.

    Quando detto però non vuol dire che non sia possibile rendere pubblici più dati utente, se si vuole. Si rimanda alla documentazione Meteor per sapere come pubblicare campi aggiuntivi della collezione Meteor.users.