Implementarea strategiilor robuste de autentificare pentru orice aplicație poate fi o sarcină descurajantă, iar aplicațiile Node.js nu fac excepție de la aceasta.
În acest tutorial, vom dezvolta o aplicație Node.js de la zero și vom folosi un middleware autentificat relativ nou, dar foarte popular - Passport pentru a avea grijă de preocupările noastre de autentificare.
Documentația pașaportului o descrie ca pe un "mijloc de autentificare simplă și de necontestat pentru Nod" și pe bună dreptate.
Furnizându-se ca middleware, Passport face o treabă excelentă în a separa celelalte preocupări ale unei aplicații web de nevoile sale de autentificare. Permite Passport-ul să fie configurat cu ușurință în orice aplicație web bazată pe Express, la fel cum am configurat alte middleware Express, cum ar fi logarea, parcurgerea caracterelor, analiza cookie-urilor, manipularea sesiunilor etc..
Acest tutorial presupune o înțelegere de bază a cadrului Node.js și Express și încercați să păstrați atenția asupra autentificării, deși facem să creăm o aplicație Express Express de la zero și progres prin adăugarea de rute către el și autentificarea unora dintre aceste rute.
Dacă aveți nevoie de ajutor cu nimic de la depanarea la funcții noi, încercați să lucrați cu unii dintre dezvoltatorii JavaScript experimentați de pe Envato Studio.
Dezvoltatori JavaScript pe Envato StudioPassport-ul ne oferă 140 de mecanisme de autentificare din care să alegeți. Puteți autentifica împotriva unei instanțe de bază de date locale sau la distanță sau puteți utiliza autentificarea unică utilizând furnizorii de servicii OAuth pentru Facebook, Twitter, Google etc. pentru a vă autentifica prin conturile dvs. de social media sau puteți alege dintr-o listă extinsă de furnizori care acceptă autentificarea cu Passport și furnizați un modul de nod pentru asta.
Dar nu vă faceți griji nu: Nu trebuie să includeți nici o strategie / mecanism pe care aplicația dumneavoastră nu are nevoie. Toate aceste strategii sunt independente unul de celălalt și sunt împachetate ca module separate de noduri care nu sunt incluse în mod prestabilit când instalați middleware-ul Passport: npm introduceți pașaportul
În acest tutorial, vom folosi Strategia Locală de autentificare a Passport și vom autentifica utilizatorii împotriva unei instanțe Mongo DB configurate local, stocând detaliile utilizatorului în baza de date. Pentru utilizarea strategiei locale de autentificare, trebuie să instalați modulul pașaport-local: npm instala pașaport-local
Dar așteptați: Înainte de a porni terminalul și de a începe să executați aceste comenzi, să începem prin construirea unei aplicații Express de la zero și să adăugăm câteva rute spre el (pentru conectare, înregistrare și acasă) și apoi să încercăm să adăugăm middleware-ul nostru de autentificare. Rețineți că vom folosi Express 4 în scopul acestui tutorial, dar cu unele diferențe minore Passport funcționează la fel de bine cu Express 3, precum și.
Dacă nu ați făcut-o deja, atunci mergeți mai departe și instalați Express & generator generator pentru a genera o aplicație boilerplate executând pur și simplu exprima pașaport-mongo
pe terminal. Structura aplicației generate ar trebui să arate astfel:
Să eliminăm câteva dintre funcțiile implicite pe care nu le vom folosi - mergeți mai departe și ștergeți users.js
și eliminați referințele din app.js
fişier.
Deschide package.json
și adăugați dependențele pentru pașaport
și pașaport locale
modul.
"pașaport": "~ 0.2.0", "pașaport local": "~ 1.0.0"
Deoarece vom salva detaliile utilizatorilor în MongoDB, vom folosi Mongoose ca instrument de modelare a datelor obiect. O altă modalitate de a instala și a salva dependența package.json
se introduce prin:
npm instala mongoose - salveaza
package.json
ar trebui să arate astfel:
Acum, instalați toate dependențele și executați aplicația boilerplate executând npm install && npm start
. Acum va descărca și instala toate dependențele și va porni serverul de noduri. Puteți verifica aplicația de bază Express la http: // localhost: 3000 / dar nu este nimic de văzut.
Foarte curând, vom schimba acest lucru creând o aplicație expresă cu drepturi depline, care solicită afișarea unei pagini de înregistrare pentru un utilizator nou, autentificarea unui utilizator înregistrat și autentifică utilizatorul înregistrat utilizând Passport.
Din moment ce vom salva detaliile utilizatorului în Mongo, să creăm un model de utilizator în Mongoose și să salvăm acel în modele / user.js
în aplicația noastră.
var mongoose = necesită ("mongoose"); module.exports = mongoose.model ('Utilizator', username: String, parola: String, email: String, gen: String, adresa: String);
Practic, creăm un model de Mongoose prin care putem efectua operațiuni CRUD pe baza de date de bază.
Dacă nu aveți instalat local Mongo, vă recomandăm să utilizați servicii de bază de date în cloud, cum ar fi Modulus sau MongoLab. Crearea unei instanțe de lucru MongoDB utilizând aceste funcții nu este numai gratuită, ci este doar o chestiune de câteva clicuri.
După ce creați o bază de date pentru unul dintre aceste servicii, acesta vă va oferi un URI de bază de date cum ar fiMongoDB: //
care pot fi folosite pentru a efectua operațiuni CRUD pe baza de date. Este o idee bună să păstrați configurația bazei de date într-un fișier separat, care poate fi tras sus ca și când este necesar. Ca atare, vom crea un modul nod db.js
care arată ca:
module.exports = 'url': 'mongodb: //: @ Novus.modulusmongo.net: 27017 / '
Dacă sunteți ca mine, folosiți o instanță locală Mongo, atunci este timpul să începeți mongod
daemon și db.js
ar trebui să arate ca
module.exports = 'url': 'mongodb: // localhost / passport'
Acum folosim această configurație app.js
și conectați-l folosind API-urile Mongoose:
var dbConfig = cer ('./ db.js'); var mongoose = necesită ("mongoose"); mongoose.connect (dbConfig.url);
Passport oferă doar mecanismul de gestionare a autentificării, lăsându-se în sarcina noastră de a implementa noi sesiuni de lucru și pentru care vom folosi sesiunea expresă. Deschide app.js
și lipiți codul de mai jos înainte de configurarea rutelor:
// Configurarea pașaportului pașaportului var = necesită ("pașaport"); var expressSession = necesită ("sesiune expresă"); app.use (expresSession (secret: 'mySecretKey'))); app.use (passport.initialize ()); app.use (passport.session ());
Acest lucru este necesar deoarece dorim ca sesiunile noastre de utilizatori să fie persistente în natură. Înainte de a rula aplicația, trebuie să instalăm sesiunea expresă și să o adăugăm în lista noastră de dependență package.json
. Pentru a face acest tip npm instalează -save expres-session
De asemenea, pașaportul trebuie să serializeze și să deserializeze instanța utilizatorului dintr-un magazin de sesiuni pentru a susține sesiunile de conectare, astfel încât fiecare solicitare ulterioară să nu conțină acreditările utilizatorului. Acesta oferă două metode serializeUser
și deserializeUser
în acest scop:
passport.serializeUser (funcție (utilizator, făcut) done (null, user._id);); passport.deserializeUser (funcția (id, done) User.findById (id, funcția (err, user) done (err, user);););
Vom defini acum strategiile Passport pentru manipulare Logare și Inscrie-te. Fiecare dintre ele ar fi un exemplu al Strategia locală de autentificare din pașaport și ar fi creat folosind passport.use ()
funcţie. Utilizăm flash-ul de conectare pentru a ne ajuta să gestionăm erorile prin furnizarea de mesaje flash care pot fi afișate utilizatorului în caz de eroare.
Strategia de conectare arată astfel:
// passport / login.js passport.use ('login', noul LocalStrategy (passReqToCallback: true, funcția (req, username, password, done) // check in mongo dacă un utilizator cu username există sau nu User. FindOne ('username': username, functie (err, user) // In cazul oricarei erori, returnati folosind metoda terminata daca err return (err); // Username nu exista, redirecționați înapoi dacă (! user) console.log ('Utilizatorul nu a fost găsit cu numele de utilizator' + nume de utilizator); Există o parolă greșită, se înregistrează eroarea dacă (! IsValidPassword (utilizator, parolă)) console.log ("Parola nevalidă"); ); // // Utilizatorul și parola se potrivesc atât cu utilizatorul, cât și cu returnul utilizatorului de la // done method, care va fi tratat ca succesul returnat făcut (null, user););));
Primul parametru la passport.use ()
este Nume a strategiei care va fi utilizată pentru a identifica această strategie atunci când va fi aplicată mai târziu. Al doilea parametru este tip a strategiei pe care doriți să o creați, aici folosim numele de utilizator-parola sau LocalStrategy. Trebuie remarcat faptul că, în mod implicit, LocalStrategy se așteaptă să găsească acreditările utilizatorului în nume de utilizator
& parola
dar ne permite să folosim și alți parametri numiți. passReqToCallback
config variabilă ne permite să accesăm cerere
obiect în apel invers, ceea ce ne permite să folosim orice parametru asociat cererii.
Apoi, folosim API-ul Mongoose pentru a găsi utilizatorul în colecția noastră de utilizatori care stau la baza pentru a verifica dacă utilizatorul este sau nu un utilizator valid. Ultimul parametru din apelul nostru: Terminat
desemnează o metodă utilă prin care am putea semnala succesul sau eșecul modulului Passport. Pentru a specifica eșecul, primul parametru ar trebui să conțină eroarea sau al doilea parametru ar trebui să evalueze la fals
. Pentru a semnifica succesul, primul parametru ar trebui să fie nul
iar al doilea parametru ar trebui evaluat la a truthy
valoare, caz în care va fi disponibilă pe cerere
obiect
Deoarece parolele sunt în mod inerent de natură slabă, ar trebui să le criptăm întotdeauna înainte de a le salva în baza de date. Pentru aceasta, utilizăm bcrypt-nodejs pentru a ne ajuta cu criptarea și decriptarea parolelor.
var isValidPassword = funcția (utilizator, parolă) return bCrypt.compareSync (password, user.password);
Dacă vă simțiți neliniștiți cu fragmentele de cod și preferați să vedeți codul complet în acțiune, nu ezitați să răsfoiți codul aici.
Acum, definim următoarea strategie care va gestiona înregistrarea unui nou utilizator și creează intrarea sa în Mongo DB care stă la baza:
passport.use ('signup', new LocalStrategy (passReqToCallback: true, funcția (req, username, password, done) findOrCreateUser = function () // găsi un utilizator în Mongo cu numele de utilizator furnizat User.findOne username ': username, functie (err, user) // In cazul oricarei erori returneaza daca (err) console.log (' Error in SignUp: + err; există dacă utilizatorul console.log ("Utilizatorul există deja"); returnul făcut (null, false, req.flash ('message', 'User Already Exists' cu acea e-mail / / creare a utilizatorului var newUser = new User (); // setarea acreditărilor locale ale utilizatorului newUser.username = numele utilizatorului; newUser.password = createHash (parola); newUser.email = req.param ("email" ; newUser.firstName = req.param ('firstName'); newUser.lastName = req.param ('lastName'); // salvează utilizatorul newUser.save (funcția (err) if (err) console.log "Eroare în salvarea utilizatorului:" + err "; arunca err; console.log (" Înregistrare utilizator reușită "); întoarcere făcută (null, newUser););); // Întârziați executarea findOrCreateUser și executați // metoda în următoarea bifă a procesului loop process.nextTick (findOrCreateUser); ); );
Aici, folosim din nou API-ul Mongoose pentru a găsi dacă există sau nu un utilizator cu numele de utilizator dat. Dacă nu, creați un utilizator nou și salvează informațiile despre utilizator în Mongo. Altfel returnați eroarea folosind Terminat
apel invers și mesaje flash. Rețineți că folosim bcrypt-nodejs
pentru a crea hash-ul parolei înainte de ao salva:
// generează hash folosind bCrypt var createHash = funcția (parola) return bCrypt.hashSync (parola, bCrypt.genSaltSync (10), null);
Dacă ar fi să vedem o vedere a păsărilor asupra aplicației noastre, ar arăta:
Acum definim rutele noastre pentru aplicație în următorul modul care ia exemplul Passport creat în app.js
de mai sus. Salvați acest modul în rute / index.js
module.exports = funcție (pașaport) / * GET pagina de conectare. * / router.get ('/', funcția (req, res) // Afișează pagina de conectare cu orice mesaj flash, dacă res.render ('index', message: req.flash );); / * Manipulare Login POST * / router.post ('/ login', passport.authenticate ('login', successRedirect: '/ home', failureRedirect: '/', failureFlash: true)); / * Pagina de înregistrare GET * / router.get ('/ registrationup', funcția (req, res) res.render ('register', message: req.flash ('message')); / * Manipulare înregistrare POST * / router.post ('/ signup', passport.authenticate ('signup', successRedirect: '/ home', failureRedirect: '/ signup', failureFlash: true)); ruter retur;
Partea cea mai importantă a fragmentului de cod de mai sus este utilizarea passport.authenticate ()
să delege autentificarea la Logare
și Inscrie-te
atunci când un HTTP POST
este făcută /Logare
și /Inscrie-te
rute respectiv. Rețineți că nu este obligatoriu să denumiți strategiile pe traseul traseului și poate fi numit orice.
Apoi, vom crea următoarele două vizualizări pentru aplicația noastră:
layout.jade
conține informații despre aspectul și stilul de bază index.jade
conține pagina de conectare care conține formularul de conectare și oferă opțiunea de a crea un cont nouextinde conținutul blocului de conținut div.container div.row div.col-sm-6.col-md-4.col-md-offset-4 h1.text-center.login-title Conectați-vă la aplicația Passport div.account- wall img (class = 'profile-img', src = "https://lh5.googleusercontent.com/-b0-k99FZlyE/AAAAAAAAAAI/AAAAAAAAAAA/eu7opA4byxI/photo.jpg?sz=120") form (class = 'form (type = 'text', nume = "username", placeholder = "Email", necesar, autofocus) introducere (type = 'password' = "parola", placeholder = "Password", necesar) buton (class = 'btn btn-lg btn-primary btn-block' ) Creați un cont #message dacă mesajul h1.text-center.error-message # message
Mulțumită lui Bootstrap, acum arată pagina noastră de conectare
Avem nevoie de încă două vizualizări pentru detalii despre înregistrare și pentru pagina de pornire a aplicației:
register.jade
conține formularul de înregistrarehome.jade
spune salut și arată logat detaliile utilizatoruluiDacă nu sunteți familiarizat cu Jade, verificați documentația.
Pașaportul, fiind un middleware, are permisiunea de a adăuga anumite proprietăți și metode la obiectele de solicitare și de răspuns și le folosește corespunzător prin adăugarea unui instrument foarte util request.logout ()
metodă care invalidează sesiunea de utilizator în afară de alte proprietăți.
/ * Manipulați Logout * / router.get ('/ signout', funcția (req, res) req.logout (); res.redirect ('/'););
De asemenea, pașaportul oferă posibilitatea de a proteja accesul la un traseu considerat a fi necorespunzător pentru un utilizator anonim. Aceasta înseamnă că dacă un utilizator încearcă să acceseze http: // localhost: 3000 / home fără autentificare în aplicație, el va fi redirecționat către pagina de pornire făcând
/ * GET Pagina principală * / router.get ('/ home', isAuthenticated, funcția (req, res) res.render ('home', user: req.user);); // ca și în cazul oricărui middleware, este foarte important să apelați următorul () // dacă utilizatorul este autentificat var isAuthenticated = funcția (req, res, next) if (req.isAuthenticated ()) returnarea următoare (); res.redirect ( '/');
Pașaportul nu este singurul jucător din această arenă când vine vorba de autentificarea aplicațiilor Node.js și există alternative ca EveryAuth, dar modularitatea, flexibilitatea, sprijinul comunității și faptul că doar un middleware face pașaportul cu siguranță o alegere mult mai bună.
Pentru o comparație detaliată între cele două, aici este o perspectivă interesantă și informativă din partea dezvoltatorului de pașaport însuși.
Dacă doriți să vedeți ce puteți face cu Node.js, verificați gama de elemente Node.js de pe Envato Market, de la un formular de contact AJAX receptiv la un shortener de adrese URL sau chiar de la o bază de date CRUD generator.