Node.js With Passport Authentication | Full Project

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] this video is sponsored by dev Mountain if you're interested in learning web development iOS or UX design dev Mountain is a 12-week design and development boot camp intended to get you a full-time position in the industry to learn more visit dev mountain comm or click the link in the description below hey what's going on guys so in this video we're going to create a nodejs and passport app and passport is used for authentication of all types you have local local strategy which is what we'll be using where we deal with the the database directly will be using MongoDB you can use OAuth so Google github Facebook Twitter you can use those to log in you can use a JSON web token if you're if you're using something like react or view or some front-end framework we're going to be doing everything on the server we're going to use ejs to display our templates we're gonna be using Mongoose to deal with MongoDB and there's some other packages we'll be using as well so it's gonna be kind of a long video I don't want to do a series I don't really like doing the series because usually the first video gets a ton of views and then it just kind of falls off so I don't really like doing those but this is a redo of a series I did about three years ago for those of you that remember I had a node in passport application that I built and the code was just horrendous I just updated it today and I think we all go through that when we look at our old code and it's just it's just cringe-worthy but I yeah I updated it so now updating the the series or rather video in this case so this is it right here this is the basically the welcome page so we can choose to register or login and you can use this kind of as a boilerplate for for any application that you want to implement server side authentication with so let's say register and we're using bootstrap we're actually using boots watch which is a themed bootstrap file and we're gonna just log in here or register I think I actually already have myself registered so let's use a different name a Sam Smith let's do Sam at gmail.com and we're using validation as well as you can see so we're going to implement that and register so now it says we're registered and we can log in so let's try it Sam at gmail.com okay once we log in it's going to take us to the dashboard and it says welcome Sam Smith and we can log out now this dashboard is protected so you have to be logged in to actually get to this route so if I log out and I go to slash dashboard you'll see that it doesn't let me it just tells me I have to login to view this resource so that's what we'll be building guys hopefully you enjoy this project we're gonna jump into MongoDB comm because we need to create our database now you can download and install it locally if you want we're going to be using Atlas which is is basically in the cloud it's really really easy to get set up I just did a video on it about a month ago some of you guys might may have seen that but you just want to register so if you go to get MongoDB fill this out and just register and then hit login and I'll go ahead and login and the way that this works is you create what's called a cluster and you get one free cluster okay and I've already created mine and called a test cluster one so if you don't have one yet just hit build new cluster choose AWS for your provider your region will probably be selected already and right here you want to choose free forever that the free plan it'll probably be selected by default and then you can rename your cluster if you want and then just hit create cluster okay and then that will create it now it does take a couple minutes to create so you might have to wait a few minutes you should be able to hit the security tab though even if it's still getting set up you do need to add a user okay because the way that you connect is through a URI string and you need to have your username and password so if you go add new user put your username your password and read and write to any database and then add user okay once you do that you want to go to IP whitelist and AD IP address and you can add your own IP address just by clicking this button or you could do just all zeros like that and that should just be you know and anyone that has your password and your username should be able to connect and that's what I have here alright so that should be all you need to do create the cluster create the user and add your IP address all right and then once your cluster set up if you click connect you can get your connect string by clicking right here connect to your application and then well either one of these the first one is going to be shorter but yeah here's the connection string and that's all like that you're gonna need and we'll implement this later on alright so now we're going to jump into vs code and I just have an empty folder called node passport login we're gonna run an NPM in it - why ok so it's going to create our package JSON file it's gonna look like this I'm gonna explain everything but I'm gonna go kind of fast because I don't want this to be too long of a video and I expect that a lot of you guys know the basics of node I do have a node.js for beginners crash course on YouTube I have an express crash course I have a node.js udemy course so there's plenty of resources as well as other other content creators so let's let's install our dependency so we're gonna say npm install or I and we want Express which is our framework we want let's see we want bcrypt because we want to encrypt our passwords I'm sorry bcrypt j/s because you never want to store plaintext passwords we need passport for authentication and then any strategy that you use with passport you need to install as a separate package so we want passport - local because we're using a local strategy we're also gonna need ejs which is our template engine that we're using and ejs by default doesn't have layouts so we're going to install Express - ejs - layouts ok we're also gonna need Mongoose to deal with MongoDB and we're gonna use connect - flash for flash messaging and connect flash depends on Express - session as well and I think let me just make sure I think that's everything that we need yeah it should be everything so let's run that and that those are all going to get installed they're gonna get added to our package Jason okay now there's one dev dependency that I want to install and that's node Mon so we're gonna say NPM install - upper case D for dev dependency and then node Mon and that's just gonna make it so that we don't have to keep restarting our server every time we make a change it'll just constantly watch it as we save our files okay so now I just want to add a couple scripts we want to start script so if we deploy this thing it'll just run node a pas it's what I'm going to call our file in fact we can change the this right here from index to app and then let's put a comma here and let's copy this down and we want a script to run our node Mon app je s and I'm going to call this dev that way we can just do NPM run dev and it will run node Mon so let's save this and close it up and we're going to create our app dot J s file and let's go ahead and bring in Express and let's just do a basic Express server first so we'll create we'll initialize our app variable with Express and let's go ahead and create a port to run our app on we're gonna use process dot e NV dot port okay in case we deploy or 5,000 on our localhost and then we're going to take our app object and call listen which will run a server we need to pass in the port and then we can do console dot log and I'm gonna put in some back ticks here so I can use a template string with a variable I'm gonna say server started on port and then put in our syntax to put in a variable all right so this should run let's go ahead and try it so I'm going to clear this up and do NPM run dev and server started on port 5,000 now we don't have a router anything so if we if we do go to localhost port 5000 it's just gonna say cannot get slash because we don't have a route for that so we're gonna have separate files for our routes so I'm going to create a folder called routes and we're gonna have two files in here index dot JSON we might as well create our users jeaious as well so anything that's like slash for instance the home page which is just / or / dashboard those are gonna go in the index J s and then user slash login user slash registers those those routes will go in here so our index J ass we're gonna be using the Express router so let's say Const Express we need to bring that in and then to use the Express router we need to create a variable called router and set that to Express dot router and then let's do module dot exports equals router and then whenever we want to create a row we simply say router dot and then whatever the method in this case it's a get request so we're gonna handle just the the homepage or the index page and for now let's just put an arrow function with a request and response object and I just want to take the response and call dot send and we'll just send the text welcome to the browser just to make sure that this works now it's not going to work just yet because in our app j/s we have to add down here say routes and we're gonna say app dot use let's say app thought use slash and I want that to pertain to say require I want that to pertain to that index file that's in the routes folder so dot slash routes slash index okay so now if we go back here and we reload we should see the text welcome okay so let's see we might as well just copy what we have in the index J s go to users paste that in and let's do slash login and we'll just send the text login so say log in page and then let's just grab this let's copy this down and this will be the register so this will be slash register okay just to get the routes down for the just displaying the pages now in our app j/s we're gonna have to do the same thing for slash users and we want that to pertain to routes slash users okay so now if I go to localhost five-thousand slash users slash login we get login and if I go to slash register we get register alright so now that we've done that let's let's start to set up our views so that we can actually see you can actually create our UI so we need to bring ejs into a PJs we actually don't need to bring it and we need to initialize it we do however need to bring in Express layouts so let's say Express layouts and we want to set that to require Express dot yeehaw - ejs - layouts and then we need to add a bit of middleware so let's say ejs we need to do app dot use Express layouts and then we need to just do app dot set and we need to set our view engine to ejs okay and make sure your X this is above this or other layouts won't work okay we'll save that now we need to create a folder for our views and inside views we're going to have a file called layout dot ejs so that's going to handle the layout around all of our views and we might as well just create all of our views will have welcome which will be the home page and you should all have ejs extensions we're gonna have login dot ajs and register dot ajs and then we're also going to have a dashboard okay and I think and we just make sure that's it we are gonna have a partial for the messages but we'll get to that later so let's go to our layout ejs and I'm gonna type this out but the other views I'm probably just gonna paste in just to save some time but the layout let's go ahead and generate a boilerplate with Emmet so we'll do exclamation enter or tab and for the title will say no dot J s and passport app and like I said we're gonna be using boots watch so let's head over to boots watch.com and basically I mean you can pick from any of these themes I'm using this journal theme so if I click download it gives us the CSS so I'm just gonna grab the link here and use that so let's let's go right here and say link paste that in we're also using font awesome so let's go to font awesome comm and grab this and put that right here okay now we are going to use the flash messages I'm using dismissible alerts the bootstrap dismissible alerts so we do need the JavaScript so we'll go to get bootstrap comm get started and then we'll grab we are we don't need the CSS we already have the boot so watch CSS but we do need these three script tags and we'll put that in the layout right above excuse me right above the ending body tag okay so let's put in the body let's do a container class and then we want to output any views that are supposed to be displayed and the way that we do that with what are we using ejs is we use an angle bracket percent and then a hyphen and then the word body and then we do percent and then bracket okay so that's gonna basically output whatever view that should be output on that page so let's save this and now if we go to welcome ejs and just put an h1 in and say welcome and save this this is what we want to render for the the index page now remember we go to our routes index j s and we have the route for that page so we're gonna do res dot render and the view that we want to render is welcome okay so now if I go back to localhost 5,000 we should see an h1 with welcome alright so what I'm gonna do now is I'm gonna paste in the the views now if you want you can go to the repository I'll have it of the link in the description too to the repository let me see it's right here so if we go to views and let's see let's go to welcome ejs and just grab this markup right here and go to welcome ejs and i'm gonna paste that in so basically it's just it's just bootstrap markup we have a row where we have margin top we're moving it down six column div here m auto will push it to the middle we're using a card so we have a border and some padding h1 has the the nodejs icon and then we just have a register and a login button so let's save that and let's check it out so if we reload it should look like that alright now let's do the register right now it's just showing the text register what we want to do is render the register template so we'll go to our route users j/s let's change this to render and then this will render login and then we want this one to res dot render register okay so let's let's grab from the repository let's grab Hugh's register ejs and I'm going to just copy this and let's go to register ejs paste that in and I'll just quickly go over this again just using the the bootstrap grid where we have an h1 with an icon register this right here this include partials I'm actually going to comment that out for now and then we have our form the action is going to go to users register and it's gonna be a post request and then we're just sending our name we're sending a you know type ID name class place holder now the value here we have some ejs in here because what this is saying is that if there's a name like if we type something in and then the validation doesn't pass we don't want the form to completely clear we want to keep whatever's in there so we're saying if typeof name is not equal to undefined then we want to display whatever that name variable is okay and we're gonna pass that into this view if we need to else then it's just going to be blank so we have this for all of the the values here okay so that's what that is and then at the bottom it just says have an account if we do then we have a link to to log in so we'll save that let's make sure that renders so if we go to register could not find the included file messages partial messages I commented it out I guess comments don't work in ejs I didn't know that all right we'll just delete it for now okay so we have our register now let's grab the login so I'll go back to the repository views login ejs basically the same thing except it goes to the login route we paste that in login ejs we'll get rid of the include for now but basically the same thing it's just getting submitted to users login so let's save that and go back okay now we should be able to click the log in here good so now the register and login pages both display we might as well do the dashboard while we're at it so let's view x' dashboard ejs which is very simple and go to dashboard ejs and paste that in ok and it's going to show it this user dot name once you're logged in once we set up passport and all that we'll have access to the user object and we'll have access to all the fields that that we have in our database all right so the ejs should be all set up so let's close that up let's just close all of these it's probably confusing you guys having so many open alright so we have our views now what I want to do is bring in mongoose connect to our database and so on so up at the top here in app j s let's bring in mongoose all right and then we want to connect to our database so we're gonna go right down here and actually you know what we need to create our config file our config folder so let's do that create a folder called config and I'm going to store the string the connection string in a file called keys Jas okay and keys Jas we're just gonna say module dot exports and we just want to explore it an object and let's do URI and then we'll put our URI in here let's see so I'm going to go back to atlas go to connect what I showed you before connect your application this one right here and we're gonna grab this okay so once we grab that we can paste that right in now I just need to put your password in right here mine's the same as my username and we'll save that and now we can bring this into our App J's file so that we can connect to our database so let's go right here let's say DB config and let's require oh sorry we want to set a variable of DB we'll set that to require our keys file which is in config slash keys and then we want the URI like that alright so set that and then we can connect to and the way that we do that is by using Mongoose and we want to use dot Connect okay and we want to pass in our DB now we're gonna get a warning spit out at us unless we put in this object here and we put in use right here use new what new URL parser and we want to set that to true if we don't do that we're gonna get some some complaints in the in the console so we want to do that and then this will return a promise so we're actually gonna go on the next line and do a dot then and a dot catch okay if there's dot catch if we have an error then let's go ahead and just console dot log it okay dot then we'll just we'll just console log let's console log MongoDB connected okay and now down here you can see my save server started and then we get MongoDB connected all right so our database is connected now what I want to do is create our model okay so we need to create a user's model or user model so we'll create a folder called models and inside there we'll create a file called user uppercase you user dot J s and then we just need to basically put in we need to create a schema with all the different fields that that we need for a user so we're gonna bring in mongoose all right and then we're gonna create our schema so let's say Const user schema and that's gonna equal new Mongoose dot schema all right and then here we're gonna pass in an object with all our fields so we're gonna have a name and we're gonna say that type is gonna be a string okay and then we want this to be required so we'll say required true all right and then let's just copy this down see we need three more so let's change this one the second one to email also going to be a string also required next one is going to be password okay and then this last one is going to be date and then date is gonna be type of date and let's get rid of let's actually change required to default because we want to have a default value of whatever the date is right now so we can do that with date dot now all right and then let's see we want to export this first we'll just put this in a variable so Const use R equals Mongoose dot model okay we want to create a model from our schema so we pass in the model name which is user and then we want to pass in our user schema and then we're just gonna export this so that we can use it in other files okay and that should do it so let's save this and we can close that up now first thing we're going to work on is is the registration let's see now since we're getting data from the form we need to add in our body parser middleware which now is part of Express before we had to install body parser as a separate module but now it's actually included with Express so let's put that right under the ejs middleware okay so we can simply say app dot use Express dot URL encoded just like before we would do body parser you want URL encoded now we can do this oops and we just want to pass in extended false that way we can get data from our form with request dot body let's see what else we doing here yeah so let's go to our routes users dot j s and remember when we submit our registration form it's gonna make a post request to slash user slash register so let's say register handle will do router dot post because we're handling a post request to users slash register we don't have to put in user because we're already in that in that file and we basically said you know connect users to this file so let's say slash register put an arrow function here request response alright and just to test this out let's do a console log and let's do request dot body ok and then I'll just do res dot send whatever hello ok I just want to I just want to see if what we pass in the form actually is gonna be in this request stop body so let's go back to our application and close this stuff up and in our application let's go to our register and let's put in some stuff here doesn't really matter what and login so that's just gonna show hello but what we want to look at is our console down here and you can see that we have all of our information from the form alright good so now let's put each thing into a variable and I'm going to use a little bit of destructuring for that so if we do Const and then some curly braces we can pull stuff out of requests dot body okay so we can pull out for instance name email password and password - okay so we're pulling those variables out now we should do you know let's let's do our validation before we actually submit hold on yeah let's let's do our validation so we're gonna actually just initialize an array called errors and let's first check for let's say check check required fields so we'll say if not name or not email basically they're all required so we're going to make sure that they're all filled in all right so if any of those if this is true then we want to take errors and we want to push onto it I'm just going to push an object with a message and the message will say please fill in all fields okay so it's the first check I want to do next let's do check passwords match so we'll say if password is not is not equal to password - then let's do errors dot push and we'll say message passwords do not match all right so this is a little next thing I want to check is to make sure that the password is at least six characters long so let's say check past length and this there's a ton of ways to do this guys if you if you want to do something else if you want to use some kind of you know third party package or something that's fine as well I'm just trying to keep it simple here so let's say if password dot length is greater than I'm sorry less than six then we want two errors dot push an object with a message then we'll say password should be at least six characters all right so that should be good for validation once we once we search for the user I'm sorry once we begin to register the user we want to search for to see if it's already there to see if that email already exists and then we'll do another error but this should be good for now so I guess what we'll do is we'll say if arrows dot length is greater than zero that means that we have an issue else let's just do res dot send and we'll just say pass okay now if there is an issue okay so if the if any of these are true then I want to re-render the registration form so let's do res don't render and we want to render register okay and then we want to pass some stuff in when we will use ejs or any template engine when we render it we can pass in values okay basically variables we want to pass in the errors okay because we want to basically loop through and display those messages we also want to pass the data in because again if we look at the registration form in our value or checking to see if name is here email or whatever because we don't want the form to completely clear when we you know when we submit the form and it's in it's not valid so let's pass in name email password and password - okay so let's save that now I mean we can try it out so if we go to register it's just refresh this so if we login if we click login we get nothing if we put a name in you can see it does stay there that's what that value does let's put an email and let's put a password so this still doesn't work the password needs to be six characters they also need to match so let's just do one through six let's make a match and login and we pass now obviously I mean we need to let the user know what the hell is going on when we when it doesn't work so we need to have some errors here some messages all right so what we'll do is create a partial so in our views we're going to create a folder called partials and all a partial is is just a piece of markup you know some HTML or whatever that we want to put inside of another template file so we're gonna call this let's say new file will call this messages dot ejs okay and then inside messages we're gonna check to see if errors exists okay because right here when we render the register we're passing in errors and when we render it normally in our get request right here we're not so we need to check to see if those errors are there so let's do that in messages now ejs syntax again is angle brackets and % so we're gonna say if and in the way this works it's very very similar to reiax JSX well it's not specific to react but it that's what it's best known for JSX is is JavaScript inside the HTML and that's basically what ejs is only instead of using you know curly braces we use these angle brackets and percent which is a bit ugly but it basically does the same thing we can do an if statement we started out oops we start it out and then we end it down here okay but we have to have these tags in order to you know for that to be JavaScript so the way that we test to see if the errors are there is by checking the type and making sure that it's if it's equal to undefined that means that they're not there so we're gonna say if typeof which is just a JavaScript expression will say if typeof errors is not equal to undefined then that means that there is an error now if there was an error we want to display that right we actually want to loop through them because errors is an array so in ejs we can use a for each so we can do I mean it's JavaScript so of course we can use it so we'll say arrows dot for each now let's see we're gonna want to it's it's kind of hard to write when you have to like separate it like this but we're gonna put a function in here okay and we have to make sure that we this has tags around it like this and up here okay so for each error let's call it error all right and then inside here is where we want to put the message now remember it's an object with a property of MSG or message so let's put that in here now if you want to actually output with ejs you want to put an equal sign so we'll say error dot msg and then we'll close it all right so let's save that and let's see if this works so if i try to submit this oh you know what we didn't insert it we didn't insert the partial into register so let's go back to register ejs and we'll go ahead and put this in here now to put in a partial and we need to just say include let me just double check the syntax here yeah so we just want to include partials slash and then messages like that should work so let's try let's save it and of course we could have just put this right inside register but I'm going to be using this in login as well so a partial is is this is a good you know good time to use a partial so it's in there we go now this looks like crap I mean we obviously want these on separate lines I want to wrap them in the bootstrap alert markup so what I'm gonna do is go to get bootstrap calm because I can't remember the the mark-up for the dismissible alert so we're gonna go to components alerts and we want dismissing okay right here because we want to be able to exit out so what I'll do is just simply grab this and inside of our messages here I'm going to replace this will put it back what we want to put in our markup and we just want to replace this line with what was just here so error dot msg all right and I guess I'll keep the alert warning that's gonna be like a yellow color so let's save that and now it should look a hell of a lot better so login oh this should actually say register not login let's change that or is it right here so register and there we go so passwords don't match and we can close them up good so we have the validation down now now it's time to actually add it to the database and notice we haven't we're not using passport yet passport is for authenticating all we're doing now is is basically uh you know creating a resource so we're creating a user and we also have to encrypt the password that's another thing we have to do so let's go back to our users route and now we want to work in here because we want to deal with you know if the validation passes so we can put a comment here say validation pass so now what do we want to do we want to use our model right because the way that Mongoose works is is you create a model such as user and then you have methods that you can call in that model like save find things like that so we're going to bring in our model up top here so we'll say Const user equals require and we're gonna go outside of the routes folder into models and then we want user okay so we should now be able to call methods on user now I want before we submit the user we want to make sure that it doesn't exist so first thing we'll do is take our user model and we'll call find one which is a mongoose method that does just that it finds one record and our query is going to go in here so we're gonna say we're email equals email okay remember we have that as a variable that's being what that's what's passed into the form and we want to match it to a user in the database now this is going to return a promise so we're gonna do say dot then and let's see you know say dot then and that's going to give us the user and what we want to do is check for that user okay so if there is a user then what I want to do is basically the same thing we did here we want to re-render the register form and we want to send along an error okay so I'm gonna just copy this and I'll put a comment here we'll just say user exists' we'll paste that in and yeah that should do it except we just want to add a new error so right here we'll say errors dot push and we want to push on msg user or let's say email is already registered and that will pass it in here okay and then this is gonna have an else and let's do well I guess we'll just keep going we'll test it after now if there isn't a user then of course we need to create a new one but we have to encrypt the password so we're also going to bring in bcrypt so up here let's say Const bcrypt and we're gonna require bcrypt dot not dot j us just be crypt j s okay and then let's go down and inside the else we're gonna say Const new user and we're gonna set this to new user okay when when you have a model and you want to create a new instance or in this case a new user we want to use the new keyword and then we want to pass in the values so we want to pass in name email and password okay now this is just es6 for this so this is the same thing same thing up here you know we're just shortening it so just in case you don't understand that syntax it's just an object now this password is gonna be plain text right in fact I guess what I'll do is I'll just console.log a new user and let's just res dot send hello I just do the res dot send so it doesn't hang what's this true is not defined required true way what oh this is in our model Oh required true this should actually be lowercase this isn't Python t.t alright alright sorry about that so let's head back over to users je s let's actually try it out and if we submit an email that isn't registered we should at least see the console log of the new user so let's do that let's try one that does exist I believe Brad at gmail exists I can actually check real quick in my cluster hopes collections let's see no it doesn't exist Kevin Smith does our Kevin at gmail so let's first try one that does exist we know Kevin at gmail exists so we'll go ahead and use that with the pass validation as well okay so emails already registered perfect so now if we use Brad at Gmail which doesn't exist we get hello and if we look in the console you can see the new user now MongoDB adds wait a minute okay MongoDB adds an underscore ID this is an object ID it adds it automatically now this is not in our database yet okay we did new user but we didn't call user save this this will create basically create the instance but we haven't saved it yet and I can show you that if I go back into Alice and I reload you can see that Brad at gmail is not here alright so we know that this is working but the password is plaintext so we certainly don't want that so let's get rid of these two lines and let's do it say hash password so we have to use bcrypt for this and what we need to do is is generate a salt okay we need to generate a salt so that we can create a hash so bcrypt has a method called gen salt okay and this takes in basically the I forget what this is it's like the number of characters or if you want to look at the the bcrypt documentation you can do that but we want to pass in ten here and then we have a callback in this case an arrow function and this is going to give us an error if there is one and then salt okay so it's going to give us our salt and then we want to do bcrypt dot hash and this hash is going to take in our plaintext password and the salt and it will give us a hash back okay so let's pass in our plaintext password so new user which is the object we created right here the password so we can get that with dot password and then it also takes in the salt that we just generated with gen salt and then it's gonna give us a call back so let's use arrow function here actually see here so this will give us let's so let's open up some curly braces here so this will give us an error possible error and the hash itself so basically the hashed password let's put this on a new line yeah we'll go like that I don't have prettier I usually have the prettier extension enabled in vs code which will kind of format everything automatically and I think that that's made me lazy with with as far as formatting my code alright so we'll get the hash right here let's check for the error actually we'll just do if error throw error okay and then we want to set the new user dot password we want to set that now to the hash okay so now it's gonna it's not going to be plain text anymore it's gonna be the hashed password and then we just need to save the user okay so we'll put a comment here we'll say set password to hashed and then let's go ahead and save the user by saying new user dot save now this will give us a promise so let's do dot then and dot catch okay if it gives us an error then we'll just console.log it and if it passes if the user gets saved then we want to redirect we want to redirect to the login page because right now we're registering a user so in this dot then it will give us the user back and let's do res dot redirect and will redirect to slash login all right so let's try this out so I'm gonna go to my register page and let's try to register myself and the password should get hashed so we'll go ahead and check this out let's register so it redirected me to all its supposed to be users login but that's that's not important let's see if it actually got saved so we'll reload and right here Brad Travis see Brad a gmail and if you look at the password it's completely hashed we also have our object ID so everything works we just need to change the redirect to go to users slash login now I would like it to say you know you're now registered you can login instead of just going to the login page so since we want let me just get rid of this since we want the message to be shown after a redirect we need to use what's called a flash message which basically stores it in a session it stores the message in a session and then displays it after the redirect what we do here when we show messages we're actually rendering a view and we're just passing this these messages in when you redirect it's a different story so we have to implement connect flash okay so that has its own middle layer so we have to go to app J s and it also needs express session which we also installed so let's see we're gonna bring it up here this is apt j s we're going to bring in flash we're going to set that to require connect that Shh and then let's also say Const session and I'll set that to require Express - session all right now the middleware for this let's put this go right under the body parser and let's put the Express session middleware and we can actually get this from the documentation just search for Express session and we want was the github page just go to it from here okay so this is the Express session github and we want this yes we want this right here if you want to copy it from the repository you can do that as well so app dot use session secret doesn't matter what this is just say secret resave we actually want to set that to true and then save on initialize we'll keep it true we don't need this cookie right here I'm not exactly sure what resave and save uninitialized is I just know that this is the correct middleware alright now we also need to add a line of middleware for connect flash which is just app dot use and we want to pass in the flash ok so now that we've done that so now we should have access to request dot flash but what I'm gonna do is since we're gonna have different different colors for different messages like like we want the yellow for errors we want green for success I'm actually going to create some global variables for that so let's say global bars and the way that we can do this is just by adding our own middleware will say app dot use and then we can just put a function in here next let's do an arrow so we can just put a function that takes in request/response next okay so anytime you want to add middleware we can just do this and we can set global variables by doing rep res dot locals dot and then whatever we want the variable in this case I'm going to use success underscore MSG and I want to set that to request dot flash because since we implemented connect flash we have this this flash object and then I want to pass in just success underscore msg like that alright and I'm going to do the same thing for error message except it's gonna be locals error message alright so and then we just need to call next okay so we just have a piece of custom middleware that has some global variables in it and we should be able to call this success message an error message and it's it's gonna come from flash now back in our users j/s when we redirect we want to call that flash message right before that so what we can do is simply pass in request dot flash and we want to pass in here success underscore message and then we'll put our text and we'll just say you are now registered let's say you are now registered and can log-in ok so I mean this takes care of creating the flash message but we have to display it so to do that I'm actually going to go into our messages ejs and we're gonna do the same type of thing we did for the errors that were passed in now the way that the the success message is gonna work this this global variable we created if it's not there it's just going to be an empty string so that's what we're gonna check for so let's go under this and let's do let's do an if so we're gonna say if and then we should be able to just check for success underscore msg and we should say if that is not equal to an empty string then we want to show the message okay but we need to put our EJ EJ s tags in here all right so if there's a success message then we want the same kind of dismissible alert so I'm going to copy this whole div paste that in but I'm gonna change it to alert success so that it's green and then instead of error dot message we simply want to put in our success underscore message variable okay and then we want to do the same for error message so I'll copy this whole thing and we'll change this to error underscore msg will change the success back to warning and change this to error message okay so this should now work because we in our actually it shouldn't work just yet because our login doesn't have the the include of the the partial right here so I'm just gonna grab this and put this in login ejs right below the h1 okay so now we'll go and try this out I'm actually going to go to my atlas and delete some of these some of these guys and delete all all right so let's go back and refresh our register and we'll just go ahead and register a user and there we go you are now registered and can login okay so we had to use the flash message because again we're redirecting so we're storing it in the session so our registration is complete now we're going to move on to the login and this is where passport comes in so let's try to think of the best way to teach this let's close up everything just to kind of start from scratch here now remember I said we're using a local strategy now we have to put this inside of a config file and we're gonna call this Passport I mean you don't have to put it in a config file but that's it I think it's the best way to do it so inside here we want to create our strategy so we're gonna say Const and we're gonna call this local strategy and this stuff is all in the documentation of Passport if you want to check that out it's not very organized but it is in there so here we want to require let's say require passports - local and then we want to say dot strategy ok so we're bringing in the local strategy and then we're also going to bring in Mongoose because we're logging in which means we need to check to see if the email matches the password matches so we're going to be using Mongoose for that so we'll require Mongoose alright and then we also want to bring in bcrypt because we need to decrypt the hash to make sure that the passwords match so let's say bcrypt are not bcrypt but compare the hash to the plaintext it's to require bcrypt j/s okay and then we're gonna bring in our user model so let's do let's see dot dot slash outside of the config then into models and then we want user alright now we want to export the strategy that we're going to create so module dot exports and this is actually going to be a function and this is going to take in passport we're gonna notice I didn't include passport up here we're gonna pass it in from the app.js file so we want to take that passport object and just say passport dot use and then we want want to say inside here new local strategy and we want to add and some options such as user name field now you could have user name if you want we're not using as user name so we want to say email is going to be our user name this should actually be a string alright so use your name field as email and then after the curly brace here we're gonna put in our arrow function and this is gonna take in three things it's gonna take in email password and done so basically the first thing we need to do is is match the user we want to first check to see if if there's an email in the database that whatever it whatever they pass in is there an email with that or I'm sorry is there a user with that email so let's say match user alright so the way that we can do this is by using Mongoose well do find one just like we did with the validation and we'll say see if there's an email that matches this email and then if there is we're gonna get a promise so we'll do dot then let's also do dot catch alright so for dart catch alright in the dot then let's see yeah inside the dot then it's going to give us the user it's either going to give us the user or it's gonna give us no I believe so we want to say user then we'll use an arrow function we'll say if not user okay so basically if there's no match then what do we want to do we want to return done okay done is this this callback here we always want to return done but we want to pass in null for the user right I believe no null is the error we don't want to send an error but we do want to say as you can see right here it's it's error the user and then options so we'll say null for the error false for the user and then for the options we're gonna put in our message okay and our message is gonna be that email is not registered okay so that's what we want to happen if the user is not there if it is there then we're gonna keep going now we haven't dealt with the password yet we've only matched the user email so obviously the next thing we want to do is match the password now to do that we need to use bcrypt because the password and the database is hashed the password they submit is not so we're gonna take bcrypt and we're gonna call a method called compare and this actually takes in the password which is going to be passed right here okay so we want to take that password and then we want to take the user dot password which is the hashed password because remember this user is coming from the database right we're finding the email if it matches it skips this and we now have the the hashed password and we're also passing in the plaintext password so we want to basically compare these and then we have a callback okay and then this callback is going to have an a possible error and then is match this will be a boolean okay so if it matches that'll be true let's just check for the error and we'll say throw error and then we'll check for his match to see if that's true okay so if is match is true that means that the user that it's passed right so what we want to return our done function and we want to pass in null for the error and then user for the user okay up here we return done but we return false for the user this time we're actually passing in the user else if it doesn't match then we want to return done we want to pass in null and we want to pass in false because it doesn't match and then a message just like we did above okay and for our message I'm just gonna say password incorrect alright now that is our local strategy now this there's a couple other things we need to do here after our exports I'm sorry not after our exports but after our strategy we need to serial it we need a method for serializing the user and deserializing the user all we have to call those methods and if we go to the passport documentation let's see and like I said this this documentation gives you everything you need but it's it's like out of order it's not it's not very easy to understand but what I'm looking for is the serialized and DC let's see so this is kind of what we were just doing no it's not that's what we still need to do what we did let's look over here yeah I hate this documentation authenticate we're gonna do that configure right here is what we just did so passport use local strategy username password done look for the user we returned done blah blah blah this is this is exactly what we just did the hell is it right here so this passport serialize user deserialize user in a typical web application that credentials used to authenticate a user will only be transmitted during the login request if authentication succeeds a session willis to be established and maintained via a cookie set in the user's browser each subsequent request will not contain credentials but rather the unique cookie that identifies the session in order to support login sessions passport will serialize and deserialize user instances to and from the session so that's what this does okay and we're gonna grab both of these copy it and we're gonna go and put this right in here alright yeah just like that and then we should be all set with this file let me just double check this make sure this is right so dun dun err oh yeah and if we want to keep this consistent we'll just we'll do arrow functions here all right so that should work now what we need to do is add a couple lines of middleware if we go back here we need these two lines right here passport initialize and passport session so copy that and we're actually gonna put that inside of our app dot J s okay and it's it's important where we put this we want to put it after the Express session middleware okay we'll put it right between that in the flash I'll say passport middleware okay that's that now passport is not defined so basically no this is this is initializing our local strategy right and it's telling us passport is not defined because we actually need to we need to require this file in our app J s and we need to pass in passport so let's go up top and we'll go yeah we'll go right up to the top here and let's say passport config we're just gonna simply require dot slash config slash passport and then we're going to pass in passport which we actually have to bring up here so Const all right so if we save that that error goes away good and this this file is now being required all right now we haven't created our route yet right when we submit this login form when we submit this it goes to users slash login it makes a post request to that route so we have to handle that we have to basically tell that route to use the local strategy so let's head back over to routes users Jas we're gonna go down to the very bottom here and let's say login handle and we're gonna take router dot post because we're here we're handling a post request to users slash login all right now let's see we're gonna have to bring in passport to this file as well so it's a Const passport and I can actually actually did show you in the documentation where it said passport authenticate that's all we need to do so if we go up here see app get log in there's the function and then the crawling passport authenticate calling the local strategy and then a function and there's there's also some options that we can put in as well so basically we have to do this and we have it's important to remember to do this at the end we have to put a set of parentheses with request/response and next all right so let's go ahead and do that okay so let's say passport dot authenticate we're using the local strategy pass in local and we're gonna pass in some parameters here I want to do a success redirect so on success what do we want to do we want to get redirect to slash dashboard alright a failure redirect we want to go back to the login page so slash users slash login and then I also want to show a flash message so we'll say failure flash and we'll set that to true okay and then we need to put like I showed you those parentheses and then request/response next okay and that should implement our strategy so we'll save that now let's go back to our application and let's try to log in with a with something that's not going to work so I'll say like tech guy info next is not defined oh we have to put next right here let's try that again okay so it just reloads the the login page right now in order to show that flash message what it does is it gives us requests I think it's requests dot error no it's actually in request dot flash error so I'm actually going to put that as a global variable like we did with the other messages so right here in global variables let's actually we'll copy this down and this is gonna be just for error because that's what it's going to be put in when we say show the flash for for Passport okay and then we're gonna go back into messages because we need to check for it and display it if it's there so it's it's basically gonna be same as this so we'll copy this except it's just error not error message so we'll get rid of that and then we'll go ahead and just show error so we'll save that now if we try to log in let's reload this we try to log in with something that email is not registered okay if we do let's see what is registered okay so we have Brad at gmail is an actual user so let's do Brad gmail but let's do the wrong password and we get password incorrect all right so let's do Brad at gmail and let's do the correct password and login and we get redirected to the dashboard now we haven't created that route yet but the login system is is working the registration is working the login is working all we have to do now is create the dashboard and the log oh so let's do that let's go to our index route and let's see we'll put a comment here this is the Welcome page and let's see we'll copy that down so we'll say / - board and we want to render the dashboard view which we'll save and then let's see our dashboard ejs this username this is going to give us an error right now because we're not passing that in yet so I'm just gonna say welcome user and then I'll put that back after but now if we go to dashboard and reload we can see it now let's give functionality to this logout okay so I'm just going to make it so that if we make a get request to slash logout then it logs us out so in our routes users j/s let's go down here and let's say log out handle and let's say router get the log out all right now logging out is actually very easy all you have to do is call request dot log out using the passport middleware it gives us the logout function we can just do that but I do want to send a flash message and redirect so I'm gonna say request dot flash whenever you want to send a flash message we can just do that request dot flash and we're gonna use success underscore message score message and then the text will just say you are logged out and then we'll redirect so res dot redirect and we want to redirect to the login okay and that should do it for a logout so let's save let's go back and click logout you are logged out now as it is I can go to dashboard even though I'm not logged in which we need to fix so what we need to do is implement ensure authenticated so let's go and let's create inside config a file called auth dot J s okay so this is like an auth guard so let's say module dot exports equals an object called and then we're going to have a property here called ensure authenticated our function called insure authenticated it's a function and then this is gonna take in request/response next and we have method attached to the request object called is authenticated so that's what we want to check for okay so passport is giving us all this stuff like this is authenticated so let's do that and then if we're authenticated we just want to simply return next else or we don't even need an else we'll just put here request dot flash and let's do an error message error message and let's say please login to view this resource and then we just want to redirect slash login okay so now we should be able to bring this this file in and we should be able to add this as middleware to any route so any route that we want to be protected we just need to add this to so let's go back to index j s and we want to want this dashboard to be protected so what we have to do is bring in say Const and sure authenticated and we want to bring that in from require and we're gonna go dot dot slash config slash off okay and then all we have to do is Pat is pass it in as a second parameter like that and now it's protected so we'll save let's reload and we can't view it okay now I want the user name to be able to show so what I'm gonna do is when I render the dashboard let's just put this on a new line when I render the dashboard I'm going to pass in an object and I want user to be set to the user because when we're logged in we have access to request dot user and then any field like name email and so on so we're gonna pass that and actually I think a better thing would be just to do quests dot user dot name and set this to name that way we don't pass the entire user in just the name and then back in our dashboard ejs let's go ahead and replace this with our ejs syntax to put in a variable and we'll just say name all right let's try that out so we'll log in we can see our dashboard and we get welcome Brad Travis E awesome we can log out all right so that's gonna be it guys I know this was a friggin long video I only expected it to be about an hour or so but I guess I guess it was quite a bit of code and don't worry if you don't understand every single line everything we did and feel free to use it as a boilerplate for future applications if you want to build a blog or something you now have authentication in place if you want to add extra fields that should be easy just update the model and you know your the stuff in your routes and so on but that's gonna be it guys I really hope you enjoyed this if you did please leave it a like and I'll see you in the next video so I just want to give a quick shout out to two of my top patrons Carlos who has his own great YouTube channel for developers and Igor from park flyer Explorer comm who offers SEO solutions for those of you that are looking to rank your website high in Google and generate more visitors so I'll have both links in the description below
Info
Channel: Traversy Media
Views: 618,452
Rating: 4.9539185 out of 5
Keywords: node.js, node, nodejs, passport.js, node passport, node login, node.js authentication, node mongodb, node mongoose, ejs
Id: 6FOq4cUdH8k
Channel Id: undefined
Length: 84min 56sec (5096 seconds)
Published: Sat Dec 29 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.