Sequelize är ett lösenbaserat Node.js ORM. Den kan användas med PostgreSQL, MySQL, MariaDB, SQLite och MSSQL. I denna handledning kommer vi att implementera autentisering för användare av en webapp. Och vi kommer att använda Passport, den populära autentiseringsprogramvaran för Node, tillsammans med Sequelize och MySQL för att genomföra användarregistrering och inloggning.
Se till att du har installerat följande på din maskin:
För denna handledning använder vi Node.js tillsammans med Express, så vi går vidare och börjar installera vad vi behöver.
Skapa en katalog för din app. Innan i den här katalogen kör du den här från din terminal eller kommandotolpekdator:
npm init
Detta initierar npm Dependency Manager. Detta kommer att presentera en rad instruktioner som vi snabbt ska gå igenom.
De stora beroenden för denna handledning är:
För att installera dem, från din terminal eller kommandotolken, kör följande efter varandra.
npm installera express - save npm installera fortsätt - save npm installera mysql - save npm installera pass - save npm installera pass-local - save npm installera body-parser - save npm installera express-session - save npm installera bcrypt-nodejs - save npm installera expresstänger - spara
Om du använder Git för det här projektet:
Skapa en .gitignore-fil i din projektmapp.
Lägg till den här raden i .gitignore-filen.
node_modules
Nu skapar vi en serverfil. Detta kommer att bli huvudfilen som heter när du skriver följande:
npm start
Detta kör appen. Du kan även köra appen genom att skriva noden server.js.
nod server.js
Sedan skapar vi en ny fil i vår projektmapp och namnger den här filen server.js.
Inuti server.js fil klistrar vi in följande:
var express = kräver ("express"); var app = express (); app.get ('/', funktion (req, res) res.send ('Välkommen till Pass med Sequelize');); app.listen (5000, funktion (err) om (! err) console.log ("Site is live"), annars console.log (err));
Den första raden tilldelar expressmodulen till en variabel express. Vi initierar sedan express och namnger det en variabel: app.
Då gör vi app lyssna på porten 5000. Du kan välja ett gratis portnummer på din dator.
Därefter kallar vi app.get ()
express routing funktion för att svara med "Välkommen till Passport med Sequelize" när en GET-begäran görs till "/".
För att testa på din dator, kör det här inifrån din projektmapp:
nod server.js
Om du ser texten "Välkommen till Pass med Sequelize" när du besöker http: // localhost: 5000 / så gratulerar! Annars kontrollera att du har gjort allt precis som det står ovan.
Därefter importerar vi några moduler vi behöver, till exempel pass, express-session och kroppsparser.
Efter var app = express ()
vi lägger till följande rader:
var pass = kräver ('pass') var session = kräver ("express-session") var bodyParser = kräver ("body-parser")
I de två första raderna importerar vi passmodulen och expressutgången, som vi båda måste hantera autentisering.
Sedan importerar vi kroppsparser-modulen. Detta extraherar hela kroppsdelen av en inkommande förfrågan och exponerar den i ett format som är lättare att arbeta med. I det här fallet använder vi JSON-formatet.
För att låta vår app använda kroppspersaren lägger vi till dessa rader några mellanslag under importlinjerna:
// För BodyParser app.use (bodyParser.urlencoded (extended: true)); app.use (bodyParser.json ());
Därefter initierar vi pass och express session och pass-session och lägger till dem både som middleware. Vi gör detta genom att lägga till dessa rader några mellanslag efter importen av bodyParser.
// För Pass app.use (session (secret: 'keyboard cat', resave: true, saveUnitialized: true)); // session hemlig app.use (passport.initialize ()); app.use (passport.session ()); // ihållande login sessioner
Vi kommer att börja arbeta med den faktiska autentiseringen nu.
Vi gör det i fyra steg:
Först skapar vi en databas i MySQL. Ge det ditt föredragna namn. För denna tutorials skull, låt oss skapa en databas som heter sequelize_passport
i MySQL.
Då ställer vi upp konfigurationen för att hantera DB-detaljer.
Låt oss först importera dot-env-modulen för att hantera miljövariabler.
Kör detta i din rotprojektmapp:
npm installera - spara dotenv
Sedan importerar vi den i huvudserverfilen server.js, strax under den andra importen.
var env = kräver ('dotenv'). last ();
Därefter skapar vi en fil i vår projektmapp och heter den .env.
Det här nästa steget att följa är valfritt om du inte använder Git:
Vi lägger till .env-filen i din .gitignore-fil.
Din .gitignore-fil ska se ut så här:
node_modules .env
Därefter lägger vi till vår miljö i .env-filen genom att lägga till den här raden:
NODE_ENV = 'utveckling'
Då skapar vi en config.json-fil som kommer att användas av Sequelize för att hantera olika miljöer.
Det första du behöver göra är att skapa en mapp som heter config
i vår projektmapp. Inne i den här mappen skapar vi en config.json fil. Den här filen ska ignoreras om du trycker på ett förråd. För att göra detta, lägg till följande kod till din .gitignore:
config / config.json
Sedan klistar vi in följande kod i vår config.json-fil.
"användarnamn": "root", "lösenord": null, "databas": "sequelize_passport", "värd": "127.0.0.1", "dialekt": "mysql", "test" : "", "dialekt": "mysql", "produktion": "användarnamn": "", "användarnamn": "", "lösenord": null, "databas" "lösenord": null, "databas": "", "värd": "127.0.0.1", "dialekt": "mysql"
Kom ihåg att ersätta värdena i utvecklingsblocket ovan med dina databasautentiseringsuppgifter.
Därefter installerar vi fortsätt med npm. För att göra detta, kör följande kommando i projektets rotmapp:
npm installera - spara fortsätt
Nu är det dags att skapa modeller mapp.
Först gör vi en katalog som heter app
i vår projektmapp.
Inuti app mapp skapar vi en ny mapp som heter modeller och skapa en ny fil med namnet index.js i modeller mapp.
Inne i index.js-filen klistar vi in koden nedan.
"använd strikt"; var fs = kräver ("fs"); var sökväg = kräver ("sökväg"); var Sequelize = kräver ("fortsätt"); var env = process.env.NODE_ENV || "utveckling"; var config = kräver (path.join (__ dirname, '...', 'config', 'config.json')) [env]; var följa upp = nytt Sequelize (config.database, config.username, config.password, config); var db = ; fs .readdirSync (__ dirname) .filter (funktion (fil) return (file.indexOf ("."! == 0) && (fil! == "index.js");) .Ever (funktion ) var model = sequelize.import (path.join (__ dirname, fil)); db [model.name] = model;); Object.keys (db) .forEach (funktion (modellnamn) if ("associate" i db [modelName]) db [modelName] .associate (db);); db.sequelize = sequelize; db.Sequelize = Sequelize; module.exports = db;
Den här filen används för att importera alla modeller som vi placerar i modeller mapp och exportera dem.
För att testa att allt är bra lägger vi till det i vår server.js-fil.
// Modeller var modeller = kräver ("./app / models"); // Synkronisera databas models.sequelize.sync (). Då (funktion () console.log ("Trevligt! Databasen ser bra ut")). Fånga (funktion (err) console.log (fel, "någonting gick fel med databasuppdateringen! "));
Här importerar vi modellerna och ringer sedan funktionen Sequelize sync.
Kör detta för att se om allt är bra:
nod server.js
Om du får meddelandet "Site is live Nice! Databas ser bra ut", då har du ställt in Sequelize framgångsrikt.
Om inte, vänligen gå försiktigt över stegen ovan och försök att felsöka problemet med hjälp.
Nästa sak vi ska göra är att skapa användarmodellen, som i grunden är användarbordet. Detta kommer att innehålla grundläggande användarinformation.
I vår modeller mapp, skapar vi en fil och heter den user.js. Den fullständiga sökvägen för den här filen ska vara app / modeller / user.js.
Öppna filen user.js och lägg till följande kod:
execs notEmpty: true, efternamn: typ: Sequelize.STRING, notEmpty: true, användarnamn: typ: Sequelize.TEXT, om: typ: Sequelize.TEXT, email: typ: Sequelize.STRING, validera: isEmail: true, lösenord: typ: Sequelize.STRING, allowNull: false, last_login: typ: Sequelize.DATE, status: typ: Sequelize.ENUM ('aktiv', 'inaktiv'), defaultValue : 'aktiva' ); returnera användaren;
Kör nu:
nod server.js
Du borde se den välbekanta "Webbplatsen är live. Trevlig! Databas ser bra ut.". Det betyder att våra Sequelize-modeller har synkroniserats med framgång, och om du kontrollerar din databas bör du se en användartabell med de angivna kolumnerna.
Låt oss först skapa visningen för registrering och ansluta den.
Det första du behöver göra är att importera den expressstyrda modulen som vi använder för synpunkter i denna handledning.
Lägg till den här raden i huvudstartfilen, server.js.
var exphbs = kräver ("express-handtag")
Ditt importblock ska se ut så här vid denna tidpunkt.
var express = kräver ("express") var app = express () var pass = kräver ('pass') var session = kräver ('express-session') var bodyParser = kräver ('body-parser') var env = kräver ('dotenv'). last () var exphbs = kräver ("expressstyren")
Därefter lägger vi till följande rader i vår server.js-fil.
// För Handlebars app.set ('views', './app/views') app.engine ('hbs', exphbs (extname: '.hbs')); app.set ('view engine', '. hbs');
Nu skapar vi tre mappar i vår appmapp visningar, controllers, och rutter.
I visningsmappen skapar vi en fil med namnet Bli Medlem.HBs och klistra in koden nedan i den.
Då i vår controllers mapp skapar vi en ny fil och heter den authcontroller.js.
I den här filen klistar vi in följande kontroller för den registreringsväg som vi skapar på ett ögonblick.
var exports = module.exports = exports.signup = funktion (req, res) res.render ('signup');
Därefter skapar vi en rutt för registrering. I rutemappen skapar vi en ny fil med namnet auth.js och sedan importerar vi auth-kontrollern i den här filen och definierar registreringsrutten.
var authController = kräver ('... /controllers/authcontroller.js'); module.exports = funktion (app) app.get ('/ signup', authController.signup);
Nu importerar vi denna rutt i vår server.js och skickar app som ett argument.
Lägg till följande rader på servern efter importen av modeller:
// Rutter var authRoute = kräver ('./app / routes / auth.js') (app);
Kör detta:
nod server.js
Nu, besök http: // localhost: 5000 / signup och du kommer se registreringsformuläret.
Låt oss upprepa stegen för inloggningsformuläret. Som tidigare skapar vi en fil med namnet signin.hbs i vår visningsmapp och klistra in följande HTML-kod i den:
Lägg sedan till en kontroller för inloggningen i app / styrenheter / authcontroller.js.
exports.signin = funktion (req, res) res.render ('signin');
Sedan i app / rutter / auth.js, vi lägger till en rutt för inloggning så här:
app.get ('/ signin', authController.signin);
Nu när du kör:
nod server.js
och besök http: // localhost: 5000 / signin /, du borde se inloggningsformuläret.
Det slutliga och stora steget är att skriva våra passstrategier.
I app / config, vi skapar en ny mapp som heter pass.
Sedan skapar vi en ny fil och namnger den i vår nya mapp app / config / pass passport.js. Den här filen kommer att innehålla våra passstrategier.
I passport.js, Vi använder användarmodellen och passet.
Först importerar vi bcrypt som vi behöver för att säkra lösenord.
var bCrypt = kräver ('bcrypt-nodejs');
Sedan lägger vi till ett modul.exports-block så här:
module.exports = funktion (pass, användare)
Inuti detta block initierar vi passport-lokalstrategin och användarmodellen, som kommer att överföras som ett argument. Så här gör vi det här:
module.exports = funktion (pass, användare) var User = user; var LocalStrategy = kräver ("pass-local"). Strategi;
Då definierar vi vår anpassade strategi med vår förekomst av LocalStrategy så här:
passport.use ("local-signup", nya LocalStrategy (användarnamnField: 'email', passwordField: 'password', passReqToCallback: true // tillåter oss att skicka tillbaka hela begäran till återkallelsen,));
Nu har vi förklarat vilken förfrågan (req) Fält vårt användarnamnField och passwordField (passvariabler) är.
Den sista variabla passetReqToCallback tillåter oss att skicka hela begäran till återuppringningen, vilket är särskilt användbart för att registrera dig.
Efter sista komma lägger vi till denna återuppringningsfunktion.
funktion (req, email, password, done)
I denna funktion kommer vi att hantera lagring av användarens detaljer.
Först lägger vi till vår hashed-lösenordsgenereringsfunktion i återuppringningsfunktionen.
var generateHash = funktion (lösenord) returnera bCrypt.hashSync (lösenord, bCrypt.genSaltSync (8), null); ;
Sedan började vi använda Sequelize-användarmodellen tidigare som Användare, Vi kontrollerar om användaren redan finns, och om inte lägger vi till dem.
Användare.findOne (var: email: email). Då (funktion (användare) om (användare) returnerat gjort (null, false, message: 'Den här e-posten är redan taggad'); var userPassword = generateHash (lösenord); var data = email: email, password: userPassword, förnamn: req.body.firstname, efternamn: req.body.lastname; User.create (data) .then (funktion skapad) if (! newUser) return done (null, false); om (newUser) return done (null, newUser);););
User.create ()
är en Sequelize-metod för att lägga till nya poster i databasen. Observera att värdena i data objekt har kommit från req.body objekt som innehåller inmatningen från vår anmälningsblankett.
Din passport.js ska se så här ut:
// ladda bcrypt var bCrypt = kräver ('bcrypt-nodejs'); module.exports = funktion (pass, användare) var User = user; var LocalStrategy = kräver ("pass-local"). Strategi; passport.use ("local-signup", nya LocalStrategy (användarnamnField: 'email', passwordField: 'password', passReqToCallback: true // tillåter oss att skicka tillbaka hela begäran till återkallelsen, funktionen (req, lösenord, gjort) var generateHash = funktion (lösenord) returnera bCrypt.hashSync (lösenord, bCrypt.genSaltSync (8), null);; User.findOne (where: email: email). (användaren) if (user) return done (null, false, message: 'Det här e-postmeddelandet är redan tagit'; else var userPassword = generateHash (lösenord); var data = email: email, password: userPassword, firstname: req.body.firstname, efternamn: req.body.lastname; User.create (data) .then (funktion (newUser, skapad) if (! newUser) return done (null, false); om (newUser) return done (null, newUser);););));
Nu ska vi importera strategin i server.js.
För att göra detta lägger vi till dessa rader under rutorna importera i server.js.
// ladda pass strategier kräver ('./app / config / pass / passport.js') (pass, models.user);
Din server.js ska se ut så här just nu:
var express = kräver ("express") var app = express () var pass = kräver ('pass') var session = kräver ('express-session') var bodyParser = kräver ('body-parser') var env = kräver ('dotenv'). last () var exphbs = kräver ('express-handtag') // För BodyParser app.use (bodyParser.urlencoded (extended: true)); app.use (bodyParser.json ()); // För Pass app.use (session (secret: 'keyboard cat', resave: true, saveUnitialized: true)); // session hemlig app.use (passport.initialize ()); app.use (passport.session ()); // persistenta inloggningssessioner // För hanteringsrader app.set ('views', './app/views') app.engine ('hbs', exphbs (extname: '.hbs')); app.set ('view engine', '. hbs'); app.get ('/', funktion (req, res) res.send ('Välkommen till Pass med Sequelize');); // Modeller var modeller = kräver ("./app / models"); // Rutter var authRoute = kräver ('./app / routes / auth.js') (app); // ladda pass strategier kräver ('./app / config / pass / passport.js') (pass, models.user); // Synkronisera databas models.sequelize.sync (). Då (funktion () console.log ("Trevligt! Databasen ser bra ut")). Fånga (funktion (err) console.log (fel, "någonting gick fel med databasuppdateringen! ")); app.listen (5000, funktion (err) om (! err) console.log ("Site is live"), annars console.log (err));
Nu kommer vi faktiskt att tillämpa strategin på vår /Bli Medlem rutt.
Så här gör vi det:
Först går vi till app / rutter / auth.js, och lägg till en rutt för inlägg för att registrera dig så här.
app.post ('/ signup', passport.authenticate ('local-signup', successRedirect: '/ dashboard', misslyckadRedirect: '/ signup'));
Eftersom vi behöver pass måste vi överföra det till den här metoden. Vi kan importera pass i det här skriptet eller skicka det från server.js. Låt oss göra det senare.
Ändra funktionen som exporteras i den här filen app / rutter / auth.js att ha ett pass som en parameter Koden i app / rutter / auth.js ska se ut så här efter din modifiering.
var authController = kräver ('... /controllers/authcontroller.js'); module.exports = funktion (app, pass) app.get ('/ signup', authController.signup); app.get ('/ signin', authController.signin); app.post ('/ signup', passport.authenticate ('local-signup', successRedirect: '/ dashboard', misslyckadRedirect: '/ signup'));
Sedan i server.js, vi ändrar ruttens import och lägger till pass som ett argument så här:
var authRoute = kräver ('./app / routes / auth.js') (app, pass);
Gå nu till registreringsadressen http: // localhost: 5000 / signup / och försök att registrera dig.
När du försöker anmäla dig får du ett fel "Misslyckades med att serialisera användaren i sessionen". Detta beror på att passet måste spara ett användar-ID i sessionen, och det använder det för att hantera hämtning av användarinformation när det behövs.
För att lösa detta ska vi implementera både serialiserings- och deserialiseringsfunktionerna för passet i vår app / config / pass / passport.js fil.
Först lägger vi till serialiseringsfunktionen. I den här funktionen sparar vi användar ID till sessionen.
För att göra detta lägger vi till följande rader under initialiseringen av den lokala strategin.
// serialisera passport.serializeUser (funktion (användare, gjort) gjort (null, user.id););
Därefter implementerar vi deserialiseringsfunktionen. Lägg till funktionen precis under serialiseringsfunktionen.
// deserialize user passport.deserializeUser (funktion (id, gjort) User.findById (id) .then (funktion (användare) om (användare) gjort (null, user.get ()); else done user.errors, null);););
I deserialiseringsfunktionen ovan använder vi Sequelize findById
lovar att få användaren, och om det lyckas, returneras en förekomst av Sequelize-modellen. För att få användarobjektet från denna instans använder vi funktionen Sequelize getter så här: user.get ()
.
Kör nu igen:
nod server.js
Och försök att anmäla dig. Hurray om du fick "Kan inte få / instrumentpanel"! Det betyder att vår autentisering var framgångsrik. Kom ihåg att vi omdirigerades till / dashboard i vårt passport.authenticate method in sträckor / auth.js.
Låt oss nu gå och lägga till den vägen. Lägg sedan till en middleware för att se till att sidan endast kan nås när en användare är inloggad i sessionen.
I vår app / vyer mapp skapar vi en ny fil som heter dashboard.hbs och lägg till följande HTML-kod i den.
Pass med Sequelize instrumentbräda
hurra! du är inloggad.
I sträckor / auth.js, Vi lägger till den här raden inuti module.exports blockera:
app.get ( '/ instrumentbräda', authController.dashboard);
Därefter går vi till app / styrenheter / authController.js och lägg till instrumentpanelen.
export.dashboard = funktion (req, res) res.render ('instrumentpanel');
Din AuthController.js ska se ut så här:
var exports = module.exports = exports.signup = funktion (req, res) res.render ('signup'); exports.signin = funktion (req, res) res.render ('signin'); export.dashboard = funktion (req, res) res.render ('instrumentbräda');
Nu kör appen igen och försök att registrera dig med en annan e-postadress än den som du tidigare använde. Du kommer att bli riktigt omdirigerad till /instrumentbräda rutt.
Men /instrumentbräda är inte en skyddad rutt, vilket innebär att även om en användare inte är inloggad kan de se den. Vi vill inte ha det här, så lägger vi till en /logga ut rutt för att logga ut användaren och skydda sedan rutten och testa vad vi har gjort.
Nu gör vi det:
I sträckor / auth.js vi lägger till den här raden:
app.get ( '/ utloggning', authController.logout);
Sedan lägger vi till regulatorn i app / controllers / authController.js.
exports.logout = funktion (req, res) req.session.destroy (funktion (err) res.redirect ('/'););
Kör sedan appen igen och registrera dig med en annan e-postadress.
Därefter besöker du http: // localhost: 5000 / logout för att logga ut användaren. Besök nu http: // localhost: 5000 / dashboard.
Du kommer märka att det är ganska tillgängligt. Låt oss lägga till en anpassad middleware för att skydda den här rutten.
För att göra detta öppnar vi app / rutter / auth.js och lägg till den här funktionen i module.exports blockera, under alla andra rader av kod.
funktion isLoggedIn (req, res, next) om (req.isAuthenticated ()) returnera nästa (); res.redirect ( '/ signin');
Därefter ändrar vi instrumentbrädthanteraren för att se så här ut:
app.get ('/ dashboard', isLoggedIn, authController.dashboard);
Nu när du kör appen igen och försöker besöka instrumentpanelsidan och du inte är inloggad, bör du vidarebefordras till inloggningssidan.
Puh! Det är dags att genomföra den slutliga delen: inloggningen.
Först lägger vi till en ny lokal strategi för inloggning på app / config / pass / passport.js.
// LOCAL SIGNIN passport.use ("local-signin", nytt LocalStrategy (// som standard, lokal strategi använder användarnamn och lösenord, vi kommer att åsidosätta med användarnamn för e-postadress: "email", passwordField: "password", passReqToCallback: true // tillåter oss att skicka tillbaka hela begäran till återkallelsen, funktionen (req, email, password, done) var Användare = användare; var isValidPassword = funktion (användarpass, lösenord) returnera bCrypt.compareSync (lösenord, användarpass) ; User.findOne (where: email: email). Sedan (funktion (användare) if (! om ! isValidPassword (user.password, password)) return done (null, false, message: 'Felaktigt lösenord.'); var userinfo = user.get (); returnerat färdigt (null, användarinfo); ) .catch (funktion (err) console.log ("Fel:", err); returnera gjort (null, false, message: "Något gick fel med ditt Signin"););));
I denna strategi, denisValidPassword
funktionen jämförs lösenordet inmatat med bCrypt-jämförelsemetoden eftersom vi lagrade vårt lösenord med bcrypt.
Om uppgifterna är korrekta, loggas användaren.
Gå nu till sträckor / auth.js och lägg till rutten för inlägg till /logga in.
app.post ('/ signin', passport.authenticate ('local-signin', successRedirect: '/ dashboard', misslyckadRedirect: '/ signin'));
Dina rutor / auth.js ska se ut så här när du är klar.
var authController = kräver ('... /controllers/authcontroller.js'); module.exports = funktion (app, pass) app.get ('/ signup', authController.signup); app.get ('/ signin', authController.signin); app.post ('/ signup', passport.authenticate ('local-signup', successRedirect: '/ dashboard', misslyckadRedirect: '/ signup')); app.get ('/ dashboard', isLoggedIn, authController.dashboard); app.get ('/ logout', authController.logout); app.post ('/ signin', passport.authenticate ('local-signin', successRedirect: '/ dashboard', misslyckadRedirect: '/ signin')); funktion isLoggedIn (req, res, next) om (req.isAuthenticated ()) returnera nästa (); res.redirect ( '/ signin');
Kör nu appen och försök att logga in. Du bör kunna logga in med någon av de uppgifter du använde när du registrerade dig, och du kommer att styras till http: // localhost: 5000 / instrumentbräda /.
Grattis om du gjorde det till slutet av denna handledning! Vi har framgångsrikt använt Sequelize och Passport med en MySQL-databas.
Den fullständiga koden för denna handledning finns på GitHub.
Detta avslutar vår handledning om att använda Passport för autentisering av användare med Sequelize och MySQL. Sequelize är en riktigt användbar ORM för att hantera MySQL när du använder Node. Jag har personligen funnit det mycket användbart, och du borde definitivt överväga att använda den i din nästa Node-MySQL-app.