Registration and Login with JWT Authentication Tutorial - NodeJS Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

I wish people would stop making such complex tutorials about JWT. JWT is very simple and can be fully explained in about 5-10 minutes in isolation. Authentication is its own subject and should be explained independently IMO.

It’s tutorials like this one that made JWT seem so ridiculously complex and unapproachable, but it’s mostly just because the name isn’t really appropriate. This tutorial should probably be called something like “Building a full registration and login system using JWT with NodeJS” instead.

Just my opinion, sorry for ragging on you OP.

👍︎︎ 17 👤︎︎ u/trappar 📅︎︎ Mar 09 2021 🗫︎ replies

I made this comment in a comment thread below but to avoid it being buried I'll post at the top level too. The token here is not encrypted like OP seems to think. OP said:

JWT makes it more secure as it is encrypted, so even if someone ends up finding the token they will have a hard time decrypting the payload.

I replied:

Well JWT doesn't encrypt anything by default, it's just base64 URL encoded with a SHA on the end, you can take any normal JWT and read the contents of the payload and header. You'd have to encrypt it yourself. And if you're encrypting info into a token and storing that in a cookie, you can just store the info in an encrypted cookie, no JWT needed. I didn't watch your whole video to see if you encrypted your JWT, but I believe that's what the other poster u/feketegy is getting at.

Not that I mind JWT. It's fine if the implementation is good. There's just a lot of misconceptions that get echoed when everyone wants to make auth tutorials without backgrounds in security... I see bad security practices thrown around as advice on Reddit all the time unfortunately. This last part isn't necessarily aimed at you since I didn't watch all your video, just an observation.

EDIT: Oof. I was curious and skipped ahead to the part where you create your token. Correct me if I'm wrong but you're not encrypting anything stored in your token. You use JWT.signwith no options object. The default algo is HS256, which is a HMAC, not encryption. Worse, you say:

"The token is secure because it's completely encrypted, ... we can store whatever we want inside that token"

, so you're leading people down the garden path! Paste one of your tokens here https://jwt.io/ and you'll see the payload. Good job you're not storing anything too sensitive in here in this video, someone else might though.

:/

👍︎︎ 5 👤︎︎ u/HashDefTrueFalse 📅︎︎ Mar 09 2021 🗫︎ replies

Good tutorial. But 47 mins! too long. It would be great if the tutorial is within 20 mins. Anyway good tutorial.

👍︎︎ 2 👤︎︎ u/OtherwiseFalcon 📅︎︎ Mar 09 2021 🗫︎ replies

Here is complete token based authentication node express backend with email verification and password reset via email. Follow the link in the discription..

https://youtu.be/OwkTQQkZu3Q

👍︎︎ 1 👤︎︎ u/nandymandy1 📅︎︎ Mar 09 2021 🗫︎ replies
Captions
[Music] hey guys how's it going i'm back here with another video and today i decided to bring a video which a lot of you guys have requested me for a long time and i've been putting it off for a bit however today i decided to bring this video because i know it's a topic which a lot of people have doubts on i remember when i learned authentication for the first time i had a lot of difficulties with it so i decided to make this video in order to try to make it simpler for those who are learning this for the first time i have made an authentication with jwt video in the past however that video wasn't um thorough at all it was actually decided to implement it with react as well in that video so i wasn't able to focus 100 on the on the api that i was building so i wanted to make a new video which uh i would actually it's completely different than implementation this video we're going to be storing our tokens in the cookies and i'm excited to bring this video to you guys so before we actually get into the video if you guys could leave a like that would massively help the channel it definitely helped my channel grow when you leave a like or comment down below um because that really helped the engagement and i would really appreciate if you guys could do that now as you can see right here um we already have a very simple um express api built so it's it's don't worry about this the thing is when you're learning authentication certain things doesn't like don't matter right one of the things that doesn't matter is the database you're using so for example i'm going to be using mysql but if you're not using mysql don't worry at all because it's going to be the same thing authentication doesn't have anything to like it it goes the same way with any different type of database you're using so for that reason i decided to set up all my database and um like the arm i'm using so that doesn't really matter um previous to to starting the tutorial so i'm going to be using my sql and to make the queries i can just access this variable over here um which is going to make it a lot simpler for for me to to record this video however if you're using mongodb don't worry same thing you'll see it's actually very similar so that's something i wanted to get out of the way and also i'm not going to show you guys how to build a very simple express server like this i literally just created three routes over here a register a login and a profile route because if you are not if you're a beginner to the point where you still need to learn about routes understand um what this code means then i wouldn't recommend already going in towards um learning authentication with jwt because it is a complicated topic and it might demotivate you but now that we have all of this out of the way you can see it is a very simple server um i just uh cr as i mentioned created my database then i applied a middleware so that we can accept json to our as the body object to our requests then i created three different routes over here uh an endpoint for registration and endpoint for login and then an endpoint for profile and i'll explain what it means and at the bottom i'm using sqlize as i mentioned so for the database so that just ignore this if you're not using it and we're listening to the server on port 3001 and currently what i have installed is as you can see my package.json um the only thing is important for you guys um is express and node1 mysql2 and sqlize is is what i'm using for the database so again it doesn't really matter so what we're going to do in this tutorial is basically we have a goal we have an ultimate goal which is we want to be able to create a system an api where you're able to register a user into a database so insert a user and create a new user with a username and a password and obviously you can add more fields and columns if you want to but in this tutorial i'm just going to use a username and password and then the password that we insert into our database must be hashed and what i mean by hashed is if i want to create a user and my user password is something like pedro just my name then i don't want this word to be in my database and the reason for that is because um is straight up would be very insecure what you want to do is you want to be able to hash your password into a random like um string of letters and numbers as you can see so that it won't be able even if like someone have access to your database they won't be able to see all the passwords that we need to know the hashing algorithm and hashing can't be unhashed so that's something important as well which will make it a lot more secure so now that we we registered our user we want to be able to log in with that user account right so you want to be able to have a route where you put a username and a password it checks to see if the user it like exists in the database at all then if the user exists it moves forward and checks to see if the password that is in the database is the same as the password that the user is trying to log in with right that makes sense if it isn't we say something like we return something like um username and password combination um or is wrong something like that and if it is correct we move forward and we actually create a json web token and what is a json web token it is basically a token which will allow us to create a communication between our client which is the user using our browser and our server which is our api and the thing with http which is what we're creating over here is that it is stateless meaning that we don't we can't create a variable like a variable called login in our api and have access to it in our client that wouldn't make sense so how this is what we're trying to solve right we want to be able to know if the user is logged in or not are not and also be able to whenever a user um closes a browser or leaves their computer when they come back to their browser they will still be logged in and we will still know who that user is right so that's what we're trying to do so the thing is when we create our json web token it will be an object which will contain some pieces of information and that object will exist inside of the user's browser for however long we want it to to be exist so for however long we want the user to be logged in and then we are going to use that token to be able to verify if the user is logged in or not so that's basically the idea and at the end we're going to add a token like kind of a firewall between this this endpoint right here which will have a middleware right over here checking to see if the user is logged in or not so right now if i run this this endpoint it should return as you can see adjacent same profile however after we have our token it should verify if the user is logged in and only return this if the user is authenticated or if the user is logged in so that's basically the idea and i'm sorry that it took a bit to actually explain everything however we're now going to get into the implementation which is important to understand is that i'm using um an api tester as you can see right here i'm using insomnia you can use postman you can use whatever you want i'm going to leave a link for insomnia in the description if you want to download it it's very simple you can just put routes over here as you can see i put localhost 3001 which is the router like the the url of our server and i just created the three routes over here this should actually be called um it should actually be called um register i don't know why i called it off but let's just leave it like this i don't want to rename it you can see there are very simple routes and both the login and the register accept an object with a username and a password because that's how our user will be will exist right and i've already created the table in the database it only includes username and password so if you haven't done that yet do it right now and let's actually get started to write in the code so what is the first thing we have to do we actually have to write some code so that the user can register themselves into our application right so in our register endpoint right here we want to be able to um let the user send a username and password and insert that into our database so i'm gonna come over here and the username and password will be sent through the body so i'm just gonna say const equal to rack.buddy and i'm gonna get from this body the username like this username and password and now that we have access to the username and password that the person wants to use for their registration we need to be able to hash this password remember when i explained about hashing the password so here is where we actually do this in order to hash our password i'm going to open up here my terminal and i'm going to install a package called bitcrypt so it is the probably the most famous hashing library out there so i'm just going to write yarn at bcrypt and if you're using npm you can just write npm install bicrypt and you'll see that it has finished installing and over here at the top i can just import um over here i'm just gonna give it some space i'm gonna import bitcrypt unlike this from require um big crypt so i'm just importing the package right and over here what we can do with big crypt is we can very simply just come over here and say big crypt dot hash and we can pass the password that we want to hash so what happens is here we pass a password so i imagine that i put the i want to register with a password that is like pedro right something like this um pedro so this is what we're putting inside of this inside over here because we're going to pass this password into our body and then the second argument for this function is we need to pass a number this argument is called as you can see right here the salt or rounds which basically represents a number uh representing how much you want to hash your password so that's basically the higher the number the longer it will take for some more like like the longer it will take to hash the password but then it will make it difficult like it will hash it more if you know what i mean so uh normally people just put 10 i'm not that familiar with hashing i just use hashing whenever i use the registration so this is basically my basic understanding of what it means so when we finish this we want to say dot then which will run after it hashes the password because this is a promise and we can get the final hashed password by grabbing it in our arguments our function we can say hash over here and the hash from this password will be represented by this variable so now what we can do is we can just insert this into our table right into our database so since i'm using mysql i'll just say users.create something like this users.create and i'll just pass username equal to username and password equal to hash so we're not passing the password the original password we're only passing the hash and after this is done so this might look different for you because you're using a different database i just want to return a json saying something like um user registered like this user registered and if there's any errors we need to account for um we can say something like dot catch and we can just display this error so i'm going to grab the error over here and ask something like if error then we want to return um an error message and usually what you do with error messages is you you pass a status over here which will be in the range of 400 which are the status codes for um when you have any errors and you say something like json and you pass an object with a value called error and over here i'll just pass whatever error it catches so i know this might seem confusing for you right now however remember this is it looks confusing because i'm using my sql but the idea is you only all you want to do is you want to create a user into the database you want to try to insert a user into the database and pass the hash as the password so if you're able to if there's any no issues then you return a json saying user registered which means like okay great you registered a user um everything went well but then over here i'm just catching any errors and seeing if there's any errors one possible error is um the user already existing in the database right so with many database systems you can make columns unique so what i did is in the username column i made it need to be unique so whenever someone try to enter or create a username that already exists it will be cached over here as you can see so if using mongodb this should go both ways so this is basically it for our um our register uh i'll show you guys my database right now this is my database i'm using a mysql workbench to display the database but again it doesn't really matter um i have a table over here all it has is id username and password and you can ignore both of these columns you can see that both of them are empty like all like there's no nothing in our table but now with our registration what should happen is if we run this endpoint over here this is the register endpoint as you can see and i try to register a user with the username pedro and the password pedro it should return here registration successful your user registered and let me check in my database you can see that now what happens is it created a new user in my database with the username pedro and the password isn't pedro in my database it's displaying the hashed value of our password which means it's great um we're not actually storing um the actual password in our database and if we want to create another person like paulo um just another person you'll see that like the other person will have a different hash for their password right so that's great um now we have our registration done um i just want to show you guys a final example if i try to register paolo again paolo is already existent so it should return an error as you can see right here and this is you can ignore this error it just says like um unique constraint error this is specifically for my database but this is the kind of errors you should be trying to catch so now that we have our registration done um now comes the hardest part which is how do we create our login endpoint well the thing with um logging in is we need to understand the flow right or how will this endpoint work well first of all i will make it asynchronous and the reason why i'll make it asynchronous is because constantly we will try to make um queries to our database and we need to return those information back in order for us to continue forward with our login endpoint and what do i mean by that is let's think about how this should work we should first the user should first try to log in and pass the username and password right then we should get this username and password very similar to what we did above by saying something like rec.buddy and grabbing over here the username and password though both of these will represent whatever they put um in their login form right and now what we need to do is we need to be able to search in our database in our table to see if that user already exists in our table why do we need that because if the user doesn't even exist we return a message saying something like you're trying to log in with an account that doesn't exist or user doesn't exist right and more importantly we want to find that user we want to sell we want to query that user in our database in order to know what password is in our table so that we can compare to the password that the user is trying to log in with so in order to do that you should write a select statement or a query to the database i'm going to use mysql as i mentioned and mysql will actually be very simple very simple i can just say constant user equal to a weight because we need to wait for this data to be back and i'm just going to say users.find one and i'll just say that i want to find one where um username is equal to username so we're just saying i want to i want to query a user where the username of that user is equal to the username that is trying to log in as you can see right here now that we have that done um we need to check to see if the user actually exists so in this case over here if we're trying to query this user with the same username if the user doesn't exist then this variable right here user will be null so we can just say if not user then if there isn't a user we just want to res dot status 400. dot json and we want to return adjacent with an error message similar to what we did above saying something like user doesn't exist now that we have this um error set um let's just try and test this out we're going to say res.json logged in something like this so what happens is we're going to try to find a user with the username that we try to log in with then if this user doesn't exist it automatically returns and ignores the rest it returns a response with a status of 400 and a json with an error saying user um doesn't exist right if it exists then we it should say um logged in right so let's try to see if this is working i'm going to open up insomnia over here and let's go to login so you know that in our database we only have um two users pedro and paulo and the password for both of them is just pedro like pedro like their name right so with login you can see we just have to pass a username and password as a json to the request so this is our body and you can see that we're making the correct request to our login so let's try this um pedro is the correct this is the correct combination and pedro exists in the database if i click send it should say logged in but if i try to log in with the user that doesn't exist in our database it should say and as you can see yeah it says user doesn't exist and it gives us a bad request as the the status right so you can see we are correctly um querying and checking to see if the user exists in the database so let's continue working with our code so now that we have this done what we have to do is we have to check to see if the passwords are the same so we're gonna create a variable called db password and this password should represent the password that is in the database right now so like this this hashed value over here and we're gonna to do that we can just say db password equal to user dot password or um this will change based on the database you're using we're just grabbing the password of the user with the username equal to the username that we're trying to log in with then what we have to do is we need to use big crypt in order to compare the two passwords so as i mentioned before um when you hash something it isn't like encryption you can't like unhash something like in encryption you can decrypt something but with a hash you can't unhash it when it when you turn the word pedro into a hash this is the hash forever so you can't turn this into pedro again so what happens is um we're going to get the both the the hashed password and the unhashed password so the password that user is trying to log in with and literally what big web does is it just compares both password passwords so it hashes the non-hashed password and compares to see if the hashed value of the non-hashed password is the same as the hash value of the um in the database right so in order to do that we can very simply just come over here and say bigcrypt.compair like this and in the first argument we pass the password that you're trying to use for login and the second one is the db password so it's going to compare both of them and then when when it finishes comparing we can just grab a variable called match we're going to grab it from the argument over here we can call it whatever we want i like to call it match which just represents if it is if the two passwords match or not right so if it doesn't match is what we're actually um going to check right here if it doesn't match then we want to return the status we're going to pass a 400 we're going to just return to json saying that the username and password combination is wrong so we're going to say something like um let me see wrong username and password combination like this and if it is if the if it matches then we just continue forward until over here and this is actually the last part of our login where we actually start dealing with json web tokens so let's for now just check to see if this is working um let's let's open up insomnia you can see that right now we're putting the correct password so if we try to log in with this it should it should continue saying logged in as you can see because it automatically goes through every single check the first check to see if the user name that we're putting exists in the database the second check to see if the password were inputted is the same as the password in the database and it should display um logged in as you can see but now if we try to put a different password a password that isn't the password in the database it should say um it says logged in so there's definitely an error i'm gonna check to see what error is um what's the problem with this but it should have displayed um this right here wrong username and password combination let me see yeah i'm gonna check it out and i'm gonna be back in a second oh okay guys so i it it actually worked it's just that we haven't finished our code yet um what happens is um right now we're just saying logged in automatically um while we should actually just put an else statement over here and it should like run based on we should just put logged in over here in the else because then it will run this whenever it doesn't match so let's run this again if i put pedro which is the correct password it should say i'm logged in but if i try to put a wrong password it should say wrong username and password combination and you can see the status as the request status so now we have this done we have basically alm almost everything done what happens here is that if you're creating an application you imagine you have like a react front-end or it doesn't even need to be react you just have a front-end a website right where there's a form and you try to log in what happens is right now the only thing it's doing is it's checking everything so it knows the username like it's a correct login and it just returns this right here logged in which is great because now we know in the front end that the user put the correct information because we can access the response to every request however we like we're not actually logging in right we want to be able in the front end to um whenever we close our browser to have like our like no if we're logged in or not and also whenever we make a request we want to be able to know which user is making those requests so for example if i try to if i'm on facebook and i want to go into my profile page i don't want to open a profile and see other people's profile right i want to be able to see my profile so how do they do this i don't actually know if it is exactly how they do this way they do this however it's something similar right they send a token they send a token in the request that and that token is stored in the front end so in order to do that we have to actually install the the how can i say the json web token package so we can just come here to our terminal and say yarn add json web token and also um one thing that is important and i'll explain better um later um we need we're going to be storing our jwts our json web tokens in the front end through a cookie and the reason why we do that is we need to store it somewhere in our browser somewhere that whenever the person closes the browser or closes the tab it doesn't get erased right a cookie will last as long as you determine determine it to like the the expiration date so you can just set it for like 30 days and in 30 days the user who had just logged in will be logged out and then we need to log in again so that's something that we need to do however there are other options um of places we can store however due to security issues you should never store your cookies on on places like your local storage or session storage you'll be very vulnerable to attacks um so i definitely recommend on the cookie and the cookie is still not the safest like it's not super safe right to make it as safe as possible we need to make our cookie not be accessible by someone a user through javascript in their browser right so we don't want a user to simply access that cookie in their browser so we're gonna i'm gonna show you guys how to fix that later in the video however now we're not gonna deal with that we're just going to continue and try to create our tokens and store them in cookies so to use cookies we actually need to use something called a cookie parser which is just a library which will allow us to parse any cookies that we're going to be using in our application so we're going to install both of them right here and i'm just going to let them install and i'm going to import those at the top over here to import um the cookie parser i'll just say cookie parser and it's going to be equal to require cookie parser like this and yeah that's basically it but with jwts but with jwts is a bit different and to apply this middleware we can just say app.use cookie parser and what happens here is every request that um every request um we'll apply we'll have this middleware applied and it should work if we do it like this but now we have to work with our tokens we need to create our token and we need to verify it how do we do that well i don't want to um it's already like i'm not organizing my code as you can see i'm putting everything inside of one file just for like um the video like a simple tutorials purpose however i i want to create an external file called something like jwt which will store all like all the code for dealing with jwts i recommend having a separate file whenever you can separating logic is extremely important when you're coding so that it becomes more um it becomes easier for you to read your code so we're going to create an external file called jwt and inside of here we're going to write two functions one of them is going to create a token and the other one is going to verify it's going to be a middleware which verifies if the toke if the the user has a token or not which we mentioned before um whenever we want to reach this page we wanted to only allow the user to to get a response if they are verified so this is where we're going to write the code for that so in order to actually create our token we're going to import some stuff from json web token right here we're going to import two of the main functions um from the library which is sign and verify we're going to just use sign initially but i'll show verify later as well so we're going to create a function called create token create tokens which is just going to be a function which allows us to create a token and and set that token um to the user's browser so what happens is we're going to take in a user over here and and the reason why we're doing this is because a token is like literally just a an object with information that like the data inside of that object is called the payload and the token is secure because it is completely encrypted right so that's something that we need to understand um we can store whatever we want inside of that token instead of that object however um we need to decide what would be important to store there you can store the user's username you can store their id i'm usually i would store the id so that i can use that id for every request um we can do that right here but actually i'm just going to use the username right here it's just going gonna we're gonna create a token which just has a username which we can access um whenever we want in our front end right so in order to do that we can just say const and we're gonna create a token i'm gonna call it access token and we're going to set it equal to sine which is the function from um json web tokens to create tokens and instead of here we have to pass two arguments actually three arguments right now the first argument is the payload so actually what we're going to store in this token remember we can put a username which is going to be equal to user.username and that's why i actually said that the function takes it takes in a user because when we call this function in our index.js i'm going to pass this user over here so that we have access to the username the id all the kind of stuff if i want to grab the id i can grab the id as well like user.id something like that i can store many pieces of information that allow us to constantly have access to the user so that's something that we can do with it and right over here we we need to pass as the second argument a secret so you want to keep your token secure so you can pass a secret to your token and it is extremely important if you are actually building an application to write a secret that no one will know right uh probably like a random string of letters and numbers over here i'm just going to put a random i'm just going to say jwt secret something like this and say something like please change for those um who are just copying the code um so you remember i just just never write like directly like this how i'm doing and also if you're gonna push your code to github create a dot env file so that you don't actually write the string like this right so right over here the next argument we can pass is actually the expiration date for this token so for example with an x with the token you can actually put an expiration date to this token and this is extremely important if you're working with um refresh tokens which i won't be doing in this video if you guys are interested in learning about refresh tokens um i can definitely make a video on but for now we're just not going to put the third argument any expiration date which means that our token will be act like valued forever we can can use this token forever which um it isn't a lot of like it isn't that much that big of a problem but if you guys want to learn about refresh tokens i can definitely make a video on that so what we have to do now is we need to just return this token so we're gonna say return access token so the flow of this function is we're going to receive a user in the argument we're going to generate a jwt which um the data inside of that jwt inside of that token will be just the user's username and its id and by the way i like i'm imagining that my like your user should have an id mine has because that's how mysql works however um you should have an id for each user that's why i'm putting it over here and then you put you pass a secret and that's basically it at the end we just return this access token so what we can do with it is we can just um come here at the bottom and export this function so module that exports i'm going to export create tokens over here so that we can we can have access to it in different files and now in our index.js i'm just going to import this file at the top here const equal to require and i'm going to require from um dot slash jwt and i'm just going to grab the function create token so this function should create a token and return it for us so what we can do is we can come to our over here our login and inside of this um instead of this place over here we can just before the json the rest.json logged in we can create a token so access token equal to create tokens and we can pass the user inside of here so basically we just create the token and return it and store it in the va in the variable access token so this will allow us to have access to the token that we're creating and we're passing the user that just logged in as you can see right here so finally we get to one of the last parts which is we want to create the cookie and store it in the user's browser so to actually edit like create a cookie and into the user's browser it's pretty simple we can just use express's um response object and say response.cookie over here and pass the name of the cookie so let's call it token or we can call it um access token like this and we can pass the token that we want to store so this is what we're going to store in the in the cookie um over here it's this verb over here and then we need to pass um some sort of expiration date for that cookie so this should be in milliseconds so i'm going to pass something like um 60 seconds times 60 seconds because it's 60 minutes now it's one hour this represents one hour i believe um times 24 hours because i want to represent something like 30 days and then times 30 and since this is milliseconds i need to multiply it times a thousand this is just dumb if you want to if you want to convert 30 days into milliseconds you can go on google and see that i'm just writing it like this because i don't want to waste any time but this is how i represent 30 days i'm saying that i want the cookie to be expired after 30 days so now that we actually have our cookie done um this should create a cookie in our browser or wherever we make the request so for example if i save this and let me just check if it's running yes you can see it's running and i come over here into my insomnia and i run this request to log in and i put the correct information so this over here should log in as you can see by the way i'll just open up my cookies here so you can see there's no cookies you can see your cookies in insomnia by just clicking on cookies and you can see there's no like nothing here so if i click send you should see that we logged in and if it worked now a cookie should appear over here and as you can see a cookie appears it's an access token and this is our cookie over here it is as i mentioned encrypted and apparently it's going to expire um the 6th of april of 2021 so um maybe i put the the milliseconds date wrong but um it doesn't really matter you can put this you can just search on google how like a conversion between milliseconds to days i try to put 30 days oh no actually it makes sense yeah i did it correctly because today is the 7th of march yeah so so basically this should expire in a month meaning that you should have that cookie in your browser if you close your tab if you close your if you even like turn off your computer and you come back the hook is still going to be there until it reaches the point of um for example when the age when it expires right and yeah that's basically it so we're able to create a cookie now what exactly do we do with it because um how do we check to see for example over here if we have a token and that we're like if if we have a cookie in our browser um that has a token in order to validate if we if we are authenticated to to go into this page so to do that we create a middleware and for those who don't know i have a video or completely like a complete video on middlewares and nodejs basically it's just a function that runs before a request so we can put a middleware inside of this request over here and before we read everything inside of this request it will run that function which decides whether or not we should move forward with the request or not so the idea is we're going to create a middleware which is going to determine if um if we are authenticated or not and if we are we should move forward so to do that we go here to our jwt file and we should create um our middleware inside of here so basically to create a middleware we just want to do something like this const validate token we can call it like this and it is a function but middlewares usually takes three arguments rec res and next so you're able to access the wreck and res of each request by just accessing those arguments and then next is just a function that we call when we want to move forward with the request so what we can do is we can first actually grab our token so remember when i said that um rec and res are like we can use both of them and they have access to the request we can actually use rack to access our cookies and that's what we're going to do here we're going to say const access token something like this it's equal to rec.cookies which is a function which you can access and instead of it you just pass the name of the cookie that you you created so we created a cookie called access token and that's what we're going to put over here because we want to access to see if this exists and if the user isn't authenticated the user hasn't isn't logged in logged in then obviously they won't have an access token so we can handle that by making a very simple if statement here saying if not access token because if it if they don't if they're not authenticated then this will be true um we just want to return [Music] something like res dot status so basically we say return whenever we we want to end the function or move forward we always have to put return but over here we're just going to return an error so reza status json and we're going to return an object saying error user not authenticated something like this and then what we do is we move forward again with our request and we try to validate if that token is actually um correct right over here we just um ordered to see if the user actually has something in their cookies if they don't they just need to log in um but now we actually need to check to see if the token is actually valid so how do we do that well we can just say try because we need to try catch here because we have no idea if it's going to work or not so we need to catch any any possible errors so we're going to say try catch and in our try we're going to try to verify if the token is correct so we're going to say const and then valid token we're going to create a variable called valid token which is just a boolean which basically asks which which basically represents if the token is verified if the token is correct then we're going to say valid token equals to verify which is a function we imported from json web tokens which is very similar to to the sign function so remember in big crypt um we had a function to hash a value and a function to compare if the value is correct right so it's similar to this we created our token over here it encrypted the the token and now we're just verifying to see if it is correct right so we can pass here the access token we want to verify and then we just pass the our secret right remember we created a secret which i told you guys to change i just because i just called it um jwt secret please change um but yeah we can just put it over here and you will know exactly what to do and it should return it should turn this in either true or false if it is a valid token so over here we can just ask if valid token so if it is correct then we want to do something right and i'll explain what we're going to do over here let's think about this if it is a valid token we need to find a way to determine if it is valid or not right we we might want to um keep track of the user's id we we can get pieces of information from the token right and we might want to do that but in this case over here what i like to do is sometimes i just like to keep a variable in the request um it is a boolean true or false just to keep track if the user is authenticated or not so we can do something like um rank dot authenticated so with with express you can actually just um create variables like this that can can be accessed through the request so you just create up you say rack dot and the name of the request the the variable and i was just gonna set it equal to true and why do we do that is because um if it is valid then we are definitely authenticated so we're just setting this equal to true and we can access this variable inside of like uh each the request that we put this middleware um to we can access it inside of any request that we apply this middleware to so we just want to set rec.authenticated equal to true and we want to return next and as i mentioned before the reason why we return next is because we want to move forward with the request we don't want to catch any errors we now know that we are actually authenticated we can just move forward and look at whatever is inside of here so now that we have this done we need to catch any possible errors and to catch any errors is actually pretty simple um we can just return as i mentioned um arrest dot status again and pass 400 as a status and then let's just pass in json we don't know exactly what error which we're catching here probably it is because we're not a valid token so this or whatever error occurs inside of this will be represented by this variable over here so what we can do is we can just say error equal to error so um this over here should return a status which like an error as the response right so this is basically it for the valid token middleware it's pretty simple to flow we just try to reach um the access token in our cookies if we don't have any access token in our cookies we just return something saying these are not authenticated then we try to validate that that token to see if it is exactly if it is actually the token that we're we're we're trying to access and if it is then we just create a variable in our request called authenticate it and set it equal to true and we move forward with our request if not then we just return um an error right we just return whatever error occurs in this case in this place over here so this is basically it for this um middleware we can just pass the middleware over here and now we can have access to it whenever we import this function this this file which we did actually here at the top you can see we can now just come over here and say validate token and we have access to this middleware so this is important because now what we can do is we can come inside of this app.get profile and let me just for now delete the cookie that we just created um you can see we have no cookies um if i go to profile you should see that it still works right we can see the word profile it there's nothing blocking it from happening right however if we pass this validate talking middleware over here um and this is how you pass the middleware just put it right before the the function the callback function and right after the the route definition um it should work let's let's see what happens when i click send you should see user not authenticated and the reason for that is because we don't see any cookies inside of here so let's actually uh log in and see what happens let's click on send we are logged in so there should be a cookie as you can see and now let's go to profile and as you can see we correctly showed our profile because now we are authenticated and that's that's great um so that's actually pretty much it however i want to try something else i just want to edit this value for the token i want to put something that is not correct just so we see whatever is cached because remember if it is not a valid token then it's like even though you have a token it should be valid so i'm just going to put this over here i change this value and we're going to click on done let's try to reach their profile as you can see it said error um json web token error um the jwt is more formed so basically it catches errors even if the token is malformed as i mentioned so yeah that's literally literally it um i would recommend if you if this is your first time learning about jwts learning about authentication i recommend um actually studying a lot of the theory behind it understanding um a lot about the differences between authentication and authorization i've made videos on authorization in the past last week i made a video on how to manage like user roles in ojs so if you're interested in that i'm going to leave a link in the description um i would also recommend actually trying your best to understand everything behind a token because that's something that i i put off a lot in the beginning when i first did anything related to authentication and using json web tokens i didn't understand what i was doing i just followed the tutorial on youtube and i just put it on my app and i couldn't explain what i did to anyone and that's not what you want so i would definitely recommend reading upon it if you guys want i can make a video just focused on that and yeah um so actually before we we go out i actually remember that i promised you guys to show um how can i make this a little bit more secure and that's actually what i'm going to do now um basically we have access to the cookie right you can clearly see that we can see if i log in and i'm going to try to log in right now we can see the the the cookie which means we can see the token and that's something that we don't want um in order to prevent um attacks we we definitely don't want the user to have access to their cookie because for example if a hacker hacks someone's account and they can just see the user's token then they'll have access to their account forever if we if we don't like um create something like a refresh token right um so the thing is what you want to do is you want to set this to this cookie as http only and that's the most secure way of making your storing your your jwts in your cookies um and that's why cookies are definitely better than like on using local storage or session storage because you don't want the user to have access to the cookie in their browser so how do we do that well i'm going to delete this right now and i'm just going to come to our code it's very simple we just go to where we created our token our cookie which is over here so we can just come over here to our cookie and we can just add a property called http on and set it equal to true so if we save this you'll see that now if i create this token um i just clicked um send if we go to our codecase you'll see that now it says http only it has a flag saying http only which what that do is which means that if we go to a browser and we try to write some javascript like if i came into imagine this is my um my my log right my console log in the browser and i do something like document.cookies right this won't like the cookie that we just created won't appear there because it is http only and that's perfect because um we can't um access someone's cookie based on this um there's many ways hackers can could do this if we didn't for example your cookies are in your browser forever right and they are there no matter which website you're in so someone can just create a website which grabs the user's cookie and like every single cookie it doesn't even matter if it is from your website or not just grabs all the cookies that the user has in their browser and just store them so now they have your token so that's something that we don't want and that's why we do something like this and yeah that's basically it i really hope you guys enjoyed this video this code is going to be all in the description if you want to check it out um just go it's on my github and yeah i really hope you guys enjoyed it if you have any questions please please leave a comment down below and tell me what you want to see next um subscribe because i post me three times a week i'm at university so it's a lot of work and i'm i've been loving what i'm doing but we really appreciate if you guys can leave a like because it will help my channel grow and yeah i really hope you guys enjoyed it and i see you guys next time
Info
Channel: PedroTech
Views: 9,323
Rating: undefined out of 5
Keywords: databases, mysql, nodejs, react js, express js, pedrotech, traversy media, traversymedia, clever programmer, tech with tim, freecodecamp, deved, pedro tech, jwt authentication, jwt authentication node js, authentication node js, authentication node js express mysql, node js authentication middleware, authentication tutorial, nodejs register login, bcrypt, jsonwebtoken, jsonwebtoken nodejs, jsonwebtoken express, jwt, jwt tutorial, node js authentication, json web token, node jwt
Id: b9WlsQMGWMQ
Channel Id: undefined
Length: 47min 8sec (2828 seconds)
Published: Mon Mar 08 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.