Autenticazione del sito in Node.js registrazione utente

introduzione

Proprio come l'autenticazione è importante nelle API, è anche una caratteristica importante in alcune applicazioni web, quelle con pagine e segreti che dovrebbero essere accessibili solo agli utenti registrati e autenticati.

In questo tutorial, costruirai una semplice applicazione web mentre impari come creare la registrazione dell'utente.

Impostazione dell'applicazione

Crea una nuova directory da cui lavorerai. Per il bene di questo tutorial, ho chiamato il mio sito-auth. Inizializza npm nella nuova directory appena creata. Ecco come inizializzare npm.

npm init -y 

Il -y flag dice a npm di usare le opzioni predefinite.

Modifica la parte delle dipendenze del tuo package.json file per assomigliare a quello che ho nel mio.

# package.json "name": "site-auth", "version": "1.0.0", "description": "", "main": "app.js", "scripts": "test" : "echo \" Errore: nessun test specificato \ "&& exit 1", "keywords": [], "autore": "izuchukwu1", "licenza": "ISC", "dipendenze": "bcryptjs": "^ 2.4.3", "body-parser": "^ 1.17.1", "connect-flash": "^ 0.1.1", "cookie-parser": "^ 1.4.3", "express": "^ 4.15.2", "express-handlebars": "^ 3.0.0", "express-messages": "^ 1.0.1", "express-session": "^ 1.15.2", "joi": "^ 13.0.1", "mangusta": "^ 4.11.12", "morgan": "^ 1.8.1", "passport": "^ 0.4.0", "passport-local": "^ 1.0. 0 "

Fatto questo, esegui il comando per installare le dipendenze.

installazione di npm

Crea un file nella tua directory di lavoro chiamato app.js.

Inizia richiedendo le dipendenze installate e i file necessari.

# app.js const express = require ('express'); const morgan = require ('morgan') const percorso = require ('percorso'); const cookieParser = require ('cookie-parser'); const bodyParser = require ('body-parser'); const expressHandlebars = require ('express-handlebar'); const flash = require ('connect-flash'); const session = require ('express-session'); const mongoose = require ('mangusta') const passport = require ('passport') require ('./ config / passport')

Queste dipendenze sono state installate durante l'esecuzione dell'installazione di npm. Per utilizzarli nella tua applicazione, devi richiederli e salvarli nelle rispettive costanti.

Per questo tutorial, userete MongoDB come database. Sarà necessario memorizzare le informazioni dell'utente nel database. Per lavorare con MongoDB, farai uso di Mongoose, uno strumento di modellazione MongoDB per Node.js. Configurare Mongoose è facile, come questo.

# app.js mongoose.Promise = global.Promise mongoose.connect ('mongodb: // localhost: 27017 / site-auth')

A questo punto, impostiamo il nostro middleware.

// 1 const app = express () app.use (morgan ('dev')) // 2 app.set ('views', path.join (__ dirname, 'views')) app.engine ('manubri', expressHandlebars (defaultLayout: 'layout')) app.set ('view engine', 'handlebars') // 3 app.use (bodyParser.json ()) app.use (bodyParser.urlencoded (extended: false )) app.use (cookieParser ()) app.use (express.static (path.join (__ dirname, 'public'))) app.use (session (cookie: maxAge: 60000, secret: 'codeworkrsecret' , saveUninitialized: false, resave: false)); app.use (passport.initialize ()) app.use (passport.session ()) // 4 app.use (flash ()) app.use ((req, res, next) => res.locals.success_mesages = req.flash ('success') res.locals.error_messages = req.flash ('error') next ()) // 5 app.use ('/', require ('./ routes / index'))) app.use ('/ users', require ('./ routes / users')) // 6 // cattura 404 e inoltra al gestore degli errori app.use ((req, res, next) => res.render ( 'non trovato') ); // 7 app.listen (5000, () => console.log ('Il server ha iniziato ad ascoltare sulla porta 5000!'))
  1. Express è inizializzato e assegnato a App.
  2. Il middleware per gestire le visualizzazioni è impostato. Per i punti di vista, farai uso di manubrio.
  3. Hai impostato il middleware per bodyparser, biscotto, sessione, e passaporto. Il passaporto verrà utilizzato quando gli utenti vogliono accedere.
  4. In alcuni punti, visualizzerai messaggi flash. Quindi è necessario impostare il middleware per quello, e anche creare il tipo di messaggi flash che si desidera.
  5. Middleware di route: gestirà qualsiasi richiesta inoltrata a un percorso URL. I percorsi URL specificati qui sono per l'indice e il percorso degli utenti.
  6. Middleware per gestire gli errori 404. Questo middleware si avvia quando una richiesta non viene mappata su alcun middleware creato sopra di esso.
  7. Il server è impostato per l'ascolto sulla porta 5000.

Impostazione delle viste

Crea una nuova directory chiamata visualizzazioni. All'interno della directory delle viste, creare altre due directory chiamate layout e parziali. Si desidera ottenere una struttura ad albero come questa nelle viste, quindi creare i file necessari nelle rispettive directory.

├── dashboard.handlebar ├── index.handlebar ├── layout │ └── layout.handlebar ├── login.handlebar ├── notFound.handlebar ├── partial │ └── navbar.handlebar └── registrati .manubrio

Fatto questo, è ora di rilasciare il codice.

# dashboard.handlebars  

User DashBoard

Questa è una dashboard che dovrebbe essere visibile solo agli utenti registrati. Per questo tutorial, sarà la tua pagina segreta.

Ora la pagina indice per l'applicazione dovrebbe apparire così.

# index.handlebars  

Autenticazione del sito!

Benvenuto a bordo.

L'applicazione richiede un layout che verrà utilizzato, ed ecco il layout che verrà utilizzato.

# di layout / layout.handlebars    Autenticazione del sito      #if successo_messaggi 
success_messages
/ if #if error_messages
messaggio di errore
/Se
> navbar body

Avrai bisogno di una pagina di accesso per gli utenti registrati.

# visualizzazioni / login.handlebars 

Per favore accedi


Il non trovato.manubrio il file verrà utilizzato come pagina di errore.

# visualizzazioni / notFound.handlebars  

Errore

La tua pagina di registrazione dovrebbe assomigliare a questo.

Per favore registrati


Finalmente per le tue opinioni, ecco la tua barra di navigazione.

# partial / navbar.handlebars 

Autenticazione del sito

Fatto questo, sei bravo a entrare in alcune parti profonde.

Convalida dei dati

Avrai bisogno di un modello utente. Dal codice delle viste sopra riportato, è possibile dedurre che le proprietà necessarie per il modello utente sono email, nome utente e password. Crea una directory chiamata Modelli, e un file in esso chiamato user.js.

# models / user.js // 1 const mongoose = require ('mongoose') const Schema = mongoose.Schema const bcrypt = require ('bcryptjs') // 2 const userSchema = new Schema (email: String, username: String , password: String, // 3 timestamp: createdAt: 'createdAt', updatedAt: 'updatedAt') // 4 const User = mongoose.model ('user', userSchema) module.exports = User
  1. Importa le dipendenze e le salva in costanti.
  2. Viene creato un nuovo schema. Per ogni utente, si desidera salvare il e-mail, nome utente, e parola d'ordine al database. Lo schema mostra come deve essere costruito il modello per ogni documento. Qui si desidera che email, nome utente e password siano del tipo String.
  3. Per ogni utente salvato nel database, anche tu vuoi creare timestamp. Si utilizza Mongoose per ottenere il createdAt e updatedAt, e questo viene quindi salvato nel database.
  4. Il modello è definito e assegnato a una costante chiamata Utente, che viene quindi esportato come modulo in modo che possa essere utilizzato in altre parti dell'applicazione.

Salatura e hashing della password

Non si desidera memorizzare le password degli utenti come testo normale. Ecco cosa si vuole fare quando un utente immette una password in testo normale durante la registrazione. La password di testo in chiaro deve essere sottoposta a hash utilizzando un valore che verrà generato dall'applicazione (utilizzando bcryptjs). Questa password con hash viene quindi archiviata nel database. 

Sembra fantastico, vero? Implementiamo ciò nel user.js file.

# models / user.js module.exports.hashPassword = async (password) => try const sale = Attendi bcrypt.genSalt (10) return await bcrypt.hash (password, salt) catch (errore) throw new Error ("Hashing failed", errore)

Hai appena creato un metodo che verrà chiamato negli eventi di registrazione dell'utente. Il metodo riceverà la password in testo semplice che l'utente ha inserito. Come accennato in precedenza, la password di testo in chiaro verrà sottoposta a hash utilizzando un sale generato. La password con hash verrà restituita come password per l'utente.

Rotte per indici e utenti 

Crea una nuova directory chiamata itinerari. In questa nuova directory, crea due nuovi file: index.js e users.js.

Il index.js il file sarà molto semplice. Si associerà all'indice della tua applicazione. Ricorda che hai impostato il middleware per i tuoi percorsi nel tuo app.js file quando hai fatto questo.

app.use ('/', require ('./ routes / index')) app.use ('/ users', require ('./ routes / users')))

Quindi il tuo percorso indice, che rende semplicemente la pagina indice, dovrebbe assomigliare a questo.

# routes / index.js const express = require ('express') const router = express.Router () router.get ('/', (req, res) => res.render ('index')) modulo .exports = router

Ora per il percorso degli utenti. Per ora, questo file di percorso farà quattro cose.

  1. Richiedono dipendenze Sarà necessario richiedere le dipendenze installate utilizzando NPM.
  2. Convalida gli input dell'utente. Vuoi assicurarti che l'utente non invii un modulo vuoto. Tutti gli input sono obbligatori e tutti devono essere del tipo String. L'email ha una convalida speciale chiamata .e-mail() che garantisce che ciò che viene inserito corrisponda al formato dell'email, mentre la password viene convalidata utilizzando un'espressione regolare. Per la password di conferma, si desidera che sia uguale alla password inserita. Queste convalide vengono eseguite utilizzando Joi.
  3. Configura il tuo router. Il OTTENERE richiesta rende la pagina di registrazione, mentre il INVIARE richiesta viene attivata quando l'utente preme il pulsante per inviare il modulo.
  4. Il router viene esportato come modulo.

Ecco come appare il codice.

# routes / users.js const express = require ('express'); const router = express.Router () const Joi = require ('joi') const passport = require ('passport') const User = require ('... / models / user') // schema di validazione const userSchema = Joi.object ( ) .keys (email: Joi.string (). email (). required (), username: Joi.string (). required (), password: Joi.string (). regex (/ ^ [a-zA- Z0-9] 6,30 $ /). Required (), confirmPassword: Joi.any (). Valido (Joi.ref ('password')). Required ()) router.route ('/ register' ) .get ((req, res) => res.render ('register')) .post (async (req, res, next) => try const result = Joi.validate (req.body, userSchema ) if (result.error) req.flash ('error', 'I dati immessi non sono validi. Riprovare.') res.redirect ('/ users / register') return const user = attende User.findOne ( 'email': result.value.email) if (utente) req.flash ('errore', 'Email è già in uso.') res.redirect ('/ users / register') return const hash = Attendere User.hashPassword (result.value.password) delete result.value.confirmationPassword result.value.password = hash const newUser = attendi nuovo utente (result.value) attendi newUser.save () req.flash ('success', 'Registrazione riuscita, vai avanti e accedi.') res.redirect ('/ users / login') catch (errore) ) next (errore)) module.exports = router 

Diamo un'occhiata più in profondità a ciò che sta accadendo in questo INVIARE richiesta.

I valori inseriti nel modulo di registrazione sono accessibili tramite req.body, e i valori assomigliano a questo.

valore: email: '[email protected]', nome utente: 'izu', password: 'chinedu', confirmPassword: 'chinedu',

Questo è convalidato usando il userSchema hai creato sopra e i valori immessi dall'utente vengono assegnati a un risultato chiamato costante.

Se si verifica un errore a causa della convalida, all'utente viene visualizzato un messaggio di errore e viene effettuato un reindirizzamento alla pagina di registrazione.

Altrimenti, cercheremo di scoprire se esiste un utente con lo stesso indirizzo email, in quanto non desideri che due o più utenti abbiano lo stesso indirizzo email. Se viene trovato un utente, l'utente viene informato che l'indirizzo e-mail è già in uso.

In uno scenario in cui nessun utente registrato ha quell'indirizzo e-mail, il passo successivo è quello di cancellare la password. Questo è dove si chiama il hashPassword metodo che hai creato nel tuo file user.js. La nuova password hash è assegnata a una costante denominata hash.

Non è necessario memorizzare il confirmationPassword nel database. Quindi questo è cancellato. La password disponibile dal risultato è ancora la semplice password. Poiché non si desidera archiviare la password semplice nel database, è importante riassegnare il valore della password all'hash creato. Questo è fatto con una linea di codice.

result.value.password = hash

La nuova istanza utente viene salvata nel database. Viene visualizzato un messaggio flash che indica che la registrazione è andata a buon fine e l'utente viene reindirizzato alla pagina di accesso.

Avvia il tuo server dal tuo terminale eseguendo:

nodo app.js

Indirizza il tuo browser a http: // localhost: 5000 e dovresti vedere la tua nuova app.

Conclusione

Ora sai come implementare la funzionalità di registrazione in un'applicazione web Nodo. Hai imparato l'importanza di convalidare l'input dell'utente e come farlo usando Joi. Hai anche fatto uso di bcryptjs per salare e cancellare la tua password.

Successivamente, vedrai come implementare una funzionalità di accesso per gli utenti registrati. Ho fiducia che ti sei divertito!