Passport Local Strategy Usage (Node + Passport + Express)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this video is part of the passport j/s user authentication series you can find the link to the playlist if you're just now finding this video you can find that in the video description in the last video of this series we went through how to set up the passport local strategy to authenticate users using a username and a password so we got all the codes set up and again the repo is in the description the repository for what I'm working on here but anyways we went through how to set it up how to set the code we got it working but I didn't really talk too much about how you might proceed in the future like how do you actually implement this in a web app and how can you kind of use it in custom ways so this video it's gonna be a little bit shorter but we're gonna talk about you know some of the different things that you can do with the passport middleware so to start what we're going to have to understand is that Passport dot serialize and deserialize configurations so if we open up the passport file it's these two configurations right here that we need to understand to really grasp what passport is trying to do in order to understand this a little bit better I'm gonna open up a pas and we're gonna write a very basic middleware that is just going to give us it's not gonna do anything but it's gonna give us a little bit of debugging power so we've got these middlewares working so here's where we set up the session that's another video that you should probably watch if you haven't because this is gonna feel like black magic if you don't know how the Express session middleware works so we include that here then we include the passport that initialize and passport that session middlewares right here so after those have done their work these are happening on every single route request we'll put in our custom middle so we'll say app dot use and we're gonna pass in a simple function we're just going to give it the standard parameters and then what we're gonna do in the body of it is just console that log request that session and then we will console that log request dot user so you'll see how this works the the Express session is going to create this object right here and the passport middleware should create this object here and then finally we have to call next so it doesn't crash our routes but basically every time we visit any route in this application this is going to run and we're gonna see exactly how it's working so for starters let's just get this running and visit in in the browser so we'll come to Google Chrome we'll come back to what I've got on the screen here in a second let's just go to the base route so we're at the home page and you can see in the application here's our cookie that we've set which represents the express session ID so that will we're gonna just delete this really quick so that we refresh everything so now we have a clean slate and the Express session middleware is going to recreate a new session for us to use when we press refresh so we pressed refresh it created a new session and in the console we should see that printed out because of the middleware that we just wrote right here so you see the session is going to show us the cookie and that's pretty much it you'll notice that the request dot user object is undefined right now and that is because we haven't yet authenticated our user using the passport that authenticate method so let's do that really quickly in the browser so we need to actually just visit the login route because we've already got this user in the database if you remember from last video so we will sign in and click Submit and this is the same session ID I'll come back to the code and this time we've got a different story so this time let me expand this that we can see it so here was our first go-around so this is what it printed and then this is the second time so now we have the session with the cookie but we also have this line right here and this was created by the passport middleware and when we executed the passport authenticate method which is in the login post route so right here that's what we just did and what passport did behind the scenes was create this additional property on the Express session and how we got this right here is through the passport that serialize user function so right here we ran the serialized user function we passed in the user ID and we stored it under the user property so let's go ahead and check to see if this is the actual ID of our user so it's 5 e 0 F now let's go over to the shell and we're already set up to query this so we'll say DB users dot fine and you'll see that we have the 5 e 0 F user in the database so the serialized user function when we did the passport authenticate method is going to grab that user from the database get the ID of the user and then insert that into the passport user or actually it would be the request dot session dot Passport dot user property so now when we need to grab this user from the the session we're going to use the deserialize user function so we're kind of seeing it all at once but to populate the request dot user right here this is the middleware that we just wrote to print all this stuff to the terminal in order to populate the request dot user we are going to grab the user from the database right here and based on the user ID that was provided in the session object and then we are going to attach the found user to the request dot user object so that was a mouthful and we've got a few more pieces to this puzzle so we'll come to apt J s and these two lines are playing into this equation as well so when we say passport initialize that's going to kind of rerun everything that we just did and then the passport that session is going to kind of work in the same way so every time we load a route these two middlewares are going to work together and what they're going to basically do is they're first going to check to see if this user property is not null so it would look something like this we would say if request that session dot Passport user not equal to null then we are going to know that there is a logged in user and we're going to grab this user ID from that property then once we grab that user ID from the property we're going to use the deserialize user method pass in oops pass in the user ID grab it from the database and then what we're going to do is populate the request user and set it equal to whatever user got from the database so that's basically what is happening on every single route request now if this user object is null then that means that the user is not currently logged in and we do not grab the user from the session and this property request that user is not populated if we go in the browser and we do the logout function or we visit the logout route you're going to notice the next time that we cancel that log these two properties that this user object is not going to exist so let's scroll to the scroll to the bottom save this come up here so we're at the bottom let's go to the browser and first we got to visit the protected route and when we click this button right here it's going to log us out so we click the logout and reload and come back to the terminal and now you'll see that this passport object is going to not have this user property in other words we are not logged in now you might say okay this is a lot to look at and it's a lot of kind of funky logic to go through every time we want to figure out if our user is logged in or not and luckily we have some methods built onto this request object to kind of do this logic for us these methods were defined by the passport middleware with a passport local middleware and we can see this if we visit the repository so this module the request dot j/s module is where this is going to kind of happen or where these are defined and you'll see a couple properties attached to the request object so the first one is the login property and this is actually called by default when we use the passport dot authenticate method so we don't really have to ever use this on our own if we're using the passport authenticate method now what's useful to us is the last three properties so first we have request dot logout so anytime that we want to log our user out we just call this method and you'll see that I do this when we had clicked that logout button you'll see in the route for the logout route somewhere down here so here's my logout route and you can see that I have called that method right there which is basically going to delete the request dot session dot passport dot user property from the session so that's all that that's doing in the next time we call the passport initialize in Passport dot session middlewares which happens on every route it's going to check that property see that it's null and pretty much declare that the user has been logged out all right so the next one we have is the request dot is authenticated and this is a really common one we're going to use a lot and basically all this is doing is what we went through manually and there's a bunch of funky code here because it's part of the framework but basically all this code is doing is saying does the request session dot Passport dot user property exists and is in it is not null and if that is the case then we declare that the user is authenticated because the only way that that property would have been populated is after we use the passport authenticate method which is going to run the verify callback which is going to implement our custom login logic finally we have request that is unauthenticated I don't really use this it's just the opposite of the request that is authenticated so you can use it but it's not really all that complicated so we've got these methods unfortunately these are not documented very well in the passport documentation which is kind of a shame but anyways let's come back to our code and see how we might use these properties to our advantage so right now in our routes we are manually calling these things and right here we are manually checking whether the request is authenticated and then if it is we are doing something if it's not we're doing something else so in order to streamline this a little bit it would make a little bit more sense if we included this as middleware and all we're doing is checking if the user is authenticated and if the user is authenticated we just call the next callback and it goes into the route and if the user is not authenticated we return some sort of 401 unauthorized err so to make our lives a lot easier let's go in the routes folder you can really put this anywhere I'm just gonna put it in the routes folder and we'll just say off middleware dot J s and in the off middle where J s I'll just take you through two different middlewares that we could implement you can get as creative as you want with this but here are some pretty standard ones that you might use so we'll say module that exports dot is off equal to a middleware function so there's the standard middleware parameters or arguments and then we're gonna do something in here to check whether the user is authenticated and if they're not we're going to return some sort of 401 unauthorized err the second one we're going to do module exports that is admin so currently we don't have an admin property on our user schema but we could easily add that and we could use this middleware to basically check whether the user is logged in and is an admin so that can help you kind of protect routes that are for admins only versus regular users we'll get to that in a second but first let's get this one done so all we're gonna do is use that request that is authenticated method that is attached from the passport middleware so we'll say if request that is authenticated then we're going to just say next and pass it on to the next middleware in the chain if the user is not authenticated we'll just return a 401 unauthorized err so we'll just say res dot status 401 dot JSON and we'll just put in a message that says you are not authorized to view this resource alright so that's pretty simple so if they're authenticated if they're logged in we're going to just pass it on to the next middleware in the chain if not we're gonna just stop it right there and return in unauthorized err alright so let's test this out so we have the is off middleware if we come to our route let's do this let's kind of refactor this so in our protected route we're going to return res dots and you made it to the route so something to indicate to us that we successfully made it into the route and within this route we could do whatever we want we could return some sort of data and to do this we will just pass in is off as the middle we're right there and of course we need to import this at the top of this file so we will say is off equals require off middleware dot is off all right so we've got this set up and now if we try to visit the protected route we should hopefully see you made it to the route so let's try that go to Google Chrome and we're already at our protected route so oh it looks like we are not authenticated right now because we had logged out so let's login really quick so we are logged in and when we click go to protected route we should see that message that we just put there it said you made it to the route so our middleware is working now let's visit the logout route so that we can log ourselves out and then see if that other status is going to work so now we went to the logout route and we were redirected to the protected route I'm not exactly sure how that worked but we got the error message that we were expecting and if we were using you know a front end we could kind of process this error in a clean manner and give a friendly message to the user so we've got our middleware working and now all we have to do is pass in this short variable before any route that we want to protect so the next thing is just kind of an added bonus it's not necessary for all applications but it's something that kind of just stretches your creativity a little bit it gets you thinking outside of the box and we're not just constrained by some framework that tells us that we need to do it this way so in order to implement the is admin we are going to come to the database and add one more thing to this user schema so we're gonna add an admin property which is going to be a boolean and we'll save that and then we need to actually register a new user so that they have this admin property and we'll just by default put this new user as an admin let's see where that happens is going to be in the register route where are we okay so right here is where we're going to do this currently we're just passing in this data but I'm just gonna hard code in the admin property and we're gonna say true so save that we will come back to the browser and we need to go to the register route let's go to register let me get rid of this and I'm going to say Zack - and we'll do the same password one two three just so I don't forget it submit we have put this user in the database let's go ahead and check that just really quickly to make sure so we'll come to the shell DB users that find now we have two users in the database let's kind of extend this and the second user Zack - has an admin property of true so Zack the original Zack is not an admin because we haven't added that property the second one is an admin so the first user should be able to visit an admin route while the second should not so let's test that out really quickly we need to make a route that will actually test it so let's come down to protected route just copy that and instead of protected will say admin route so the first thing we want to check is that is off we kind of have some freedom how we want to do this I'm gonna go ahead and simplify things and just say is admin so we don't have to repeat it so we could do is off and then is admin and in the in in this middleware all we have to do is check whether that property exists but I'm gonna go ahead and simplify that you'll see what I mean in a second so we'll say is admin we need to import that here at the top so I know this is you know not really good coding practice we could refactor this a little bit but we'll do it just for the sake of time so we've put the is admin middleware in there we've included it in the admin route and we'll say you made it to the admin route if they successfully make it through that middleware gate so now we come back to the auth middleware and let's just copy the same exact thing except this time we're going to say if request dot is authenticated and request dot user admin since this is a boolean property we can just say this so now we have two requirements to get through this authentication middleware and then we have the same exact logic here maybe we'll change the message to say you are not authorized to view this resource because you are not in the admin all right so we've got this set up and I think we should be able to visit the route that we just created so admin route let's just manually type that into here and since we haven't I don't think we've logged in with anyone yet so let's log in with the first user so this one should not be an admin and will go to the admin route and it'll say you are not authorized to view this because you're not an admin as we would expect now let's log this user out by just going to log out and then let's go to log in we're gonna log in that second user that does have admin privileges up looks like we had some sort of login failure maybe I just typed it in wrong oh it was because I put the wrong user name in so it's not Zach one it is Zach two and one two three all right we are successfully logged in let's go to the admin route and this time we should get a success message you made it to the admin route so we've covered a good amount here but hopefully this kind of opens up your creativity into understanding how the passport local strategy works how we can use it to creatively authenticate and allow access to different resources based on whether a user is logged in or logged out based on whether a user has admin credentials and you could even go through some more complex logic if you wanted to by creating different types of middlewares I know it seems like we've already run a marathon just trying to get the passport local strategy implemented but again authentication user authentication is not an easy subject I think we kind of treat it as an easier subject because it's like okay there's only a few moving parts here it seems like on the surface but once you get into the implementation there are so many different things that you have to understand in order to debug and have a solid grasp around user authentication now we have another authentication method called the passport JWT strategy which is probably a little bit more in these days especially with single page applications like angular or react so that is going to be the next video in this series if you are happy with the passport local authentication strategy then you can just stop here but if you're wanting to continue on again the playlist is in the description if you're not following that right now the next video in that playlist is going to be the start of the passport JWT strategy if you enjoyed this video learned a lot from it give it a like and subscribe to the channel and have a great day
Info
Channel: Zach Gollwitzer
Views: 19,644
Rating: 4.9355993 out of 5
Keywords: passportjs, user authentication, nodejs user authentication, expressjs user authentication, passport local, passport jwt, javascript, express middleware, HTTP Cookies, HTTP Headers, express sessions
Id: fGrSmBk9v-4
Channel Id: undefined
Length: 26min 52sec (1612 seconds)
Published: Mon Feb 17 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.