Node.js Register & Login Tutorial - Learn how to authenticate with Node.js, MongoDB and JWT

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Thanks, Mehul ( these videos help me alot to pick up the concepts). Can you Please share the source code and What VS Code theme are you using??

👍︎︎ 1 👤︎︎ u/Akash_Rajvanshi 📅︎︎ Oct 24 2020 🗫︎ replies

For real though, why MongoDB instead of SQL? For the sake of simplicity?

Don't get me wrong I like Mongo, but a non-relational database is not going to be useful for a web app that has to handle much more than users.

👍︎︎ 1 👤︎︎ u/Harbltron 📅︎︎ Oct 24 2020 🗫︎ replies

does anyone really roll their own auth nowadays?

👍︎︎ 1 👤︎︎ u/eggn00dles 📅︎︎ Oct 24 2020 🗫︎ replies
Captions
hey everyone welcome back to another course this is gonna be a short one on a simple nodejs project which we'll be creating which was gonna be just a login logout project you are watching one of the modules of nodejs back in developer learning path and we have covered all of the previous stuff so far so if you are if you want to become a back-end developer a good back-end developer you can go ahead and start following this learning path the link for this should be in below description if you are watching this on youtube or some other platform if you are watching this on codename itself then of course you know how to follow this along so let's just go ahead and start working in this little project and we're going to be taking a look at how you can implement authentication using node.js but not only that also following some of the best practices along the way and things you should know as a good developer so that's all for this introduction video i'm going to see you in the next one really soon alright guys welcome back and in this video let's just go ahead and start our little project this is just going to be a project where we will be authenticating users and registering them with the help of usernames and passwords this is not going to be an oauth project right we're going to be coming to that later on in the in the learning path module but you should know how to register and store passwords securely and just have the whole process is going on smoothly with the actual login logout system as well so let's just go ahead and take a look you can see i have a very simple express server and this is the file structure which we have right i have installed just express at the moment and once you do that you can just set it up like this and this is the file which is being served right here right so if i go ahead and write h1 hello you could see that if i refresh this this is what we get right so first things first we have to create a registration form right so what i'm gonna do is i'm gonna very quickly create a form and i'm gonna just give it an id of registration form right and we could probably say h1 registrar registration and i'm not really gonna focus a lot into css part because our main priority would be to get node server up and working so let's just go ahead and quickly introduce two fields just input type text while you not read the value but placeholder your username or email may be whatever it is right and the second one is gonna be password and that one would be the password of the user right so once we have this going on we can just quickly throw in a script which just says that form is document.getelementbyid and we pick up the reg form element right and whenever that form submits we want to fire a listener right so i want to say register user right so now we can go ahead and create a function called register user right here which is going to receive an event just like you would have received with any other event listener like click or double click and first thing is we want to say event dot prevent default why is that because the default behavior of the forms is to refresh the page right and we don't really want refresh or navigate the page away to whatever you have specified as the action here right but we don't really want to do that we want the js to handle it so we're going to be just preventing anything which is which is the default action so we do that with even prevent default let's just go ahead and get the username and password now so i'm going to say this is going to have an id of username and this is going to have an id of password right so our username is going to be document.getelementbyid username and similar thing for password as well so there we have it right so we have username and password now we want to send this data to our node server right so when you send the data to a backend there are a multiple there are multiple ways to send some data right so the first one is obviously sending the data as json send data as json which is very common very common when you are using js right the other one is sending sending data as uh you know url encoded now by default when you use forms this is what uh is being used by default right and json is like very popular among node which is my personal observation and url encoded is very popular among backends like php right so we're going to be using json to send the data not url encoded because json brings in a lot of good support out of the box in javascript url encoded also brings that but not so much so let's just go ahead and use json to send the data and the way we we're going to do it is by just making use of a simple fetch which is a you know a utility which is provided by browser itself to make http calls and i'm just gonna say i want to send it to api slash register and i want to say the method for this would be post the headers would consist of one important header which is going to be saying content type and this is where our content type would go right so just like we mentioned this is going to be application json for us so i'm just going to keep it application json if you wanted to have a url encoded you're going to have to change the content type here but for the most part you can always keep it like this when you're sending json data now in body here is where your json would go but just before doing that you want to stringify your json right because this is the actual raw body which you write in the request right so we want to say username and password just like that so what's happening here is we are having username and password getting from the from the input fields and then we pass it along the server right and you can optionally wait on this because we already have the async in place and i can say result from server something like this and probably then i want to say i also want to convert the result from server into json so what's essentially happening just to give you an overview again we create a form whenever somebody clicks on that submit button which is not which is something we have not created yet so let's just go ahead and do that submit form so whenever somebody clicks on this this function gets called this thing runs and you know this request is made to the server and the result variable contains what the server responds so if we go ahead and do that if you go ahead and refresh this you can see we got a registration form if i go to my networks tab if i enter something and one thing you can do is just which just personally annoys me is you can just go ahead and say autocomplete has off here right refresh right here summit form and obviously we get errors because our backend is not ready yet right you can see that we get cannot post api register but if you go to headers all the way down what you're going to see is that you could see that you have username and password as empty objects so what you really want is the value not the dom objects right so let's just go ahead and refresh this and now when we submit it you can see that we get the passwords and username correctly but our backend is of course not ready so let's just go ahead and do that in the next video we're going to be doing a bunch of more changes on the front-end part not in terms of css but in terms of security we're going to be also having a recaptcha form implemented but that would be at the end of the series because we don't really want to have a lot of friction going on right away so that's all for this video i'm gonna see you in the next one really soon hey everyone welcome back and in this video let's just go ahead and take a look at what we can do on the server side to receive this data right so first things first we are seeing that the request we are making is of type post and the second thing is we are making use of json to send the data with that information that is probably enough to get us started with express so i'm going to create a new route api slash register right and this is going to be a request response sort of function and i'm just going to make this async because we're going to be making a bunch of database calls here so once we have this in place the next thing i want to do is i want to just console.log for example request.body right and what you're going to see is request.body is actually empty because by default express does not parse the json which is being sent in that request right so you're gonna not get this out of the box so for this we have to install another module and that is gonna be body parser so once oops yeah an ad body parser you can use npm as well if you want but i'm just using yarn so once you have that you can import body parser like this require body parser and once you do that you can basically go ahead and say app.use bodyparser dot json and that's it so this is just a middleware for express to decode the body which is coming in right so this would actually give you the json representation of your body if it is json if it is malformed or you know just invalid json then throw an error right so yeah that's that's basically it and if we go ahead and just say rest.json status okay right this would just take care of everything like setting the headers and everything like we used to we have to manually set headers here right but if you use rest.json on the server it will automatically set the headers so if you refresh it oops i think we have closed the server nodemonserver.js so if we refresh it we're going to see if i write this we get a 200 okay the servo says status okay but nothing is really going on right so let's just go ahead and make sure something is going on so i'm gonna bring in mongoose i already have mongoose installed you might want to do mongoose installation by saying ad mongoose or npm install mongoose whatever it is so once you bring in mongoose the next step is to connect mongoose right so i'm going to say mongoose.connect and then i'm going to specify mongodb localhost 27017 and this would be i don't know let's say database or maybe like you know login app tv something like that now if you want to know more about mongoose and you know how you work with mongodb in general then i would recommend you to go to this database introduction section where we actually cover mongodb the crux of mongodb and the crash course sort of thing in a much better way right so i won't be going through basics of mongodb and mongoose in this one i'm assuming that you are already familiar with it so there's that right um you can go ahead and you know just go ahead and pass in some parameters like use new url parser to true to you know just just get rid of those warnings you can say use unified topology as well and this will just you know just get rid of warnings right if you're somebody like me who do not really like a lot of warnings so you can have that so once we do this the next step is to create a model for our user right so i'm going to create a new folder saying model and i'm going to create a user.js right here now the reason we are creating a model is that so we actually sort of enforce a schema number one on the database and number two is that makes our life a little bit more easy in terms of managing data flow with node.js so first things first again i'm going to import mongoose from mongoose right and i'm going to create a new user schema schema like this and i'm gonna say mongoose.schema and we want to initialize it with new and here's the place where we pass in the information for our schema right so i'm gonna say username is gonna be of type string and it is always required right you cannot create a user without a username obviously and password is also gonna be of type string and it is required as well one more thing which you can do as a good practice is you can enforce a unique field test here itself right so this unique means that username has to be unique right it cannot you know two records cannot have same username so this unique by the way is implemented using indexes in mongodb right it is not like mongoose will make two calls to database to determine if the if the record is unique or not it will just make one call if mongodb allows it it's fine if it does not that means the record was not unique right so yeah that's that's pretty much it for the schema part and just to you know wrap up wrap this thing up what we're going to do is register this as a model in mongoose so i'm going to say this model is mongoose dot model and i'm going to specify this is user schema or a model or whatever you want we will not be using model like this uh but instead of exports uh let's see module dot exports model will be actually importing this file and then using the model right one quick thing again is you can do and specify the collection to be users right because you don't really want your collection to be dynamic based on the name of your model so with that being done now we can go ahead and work with the user collection once we import it so i'm going to say user is require model user right and now we can have a bunch of great methods but we have an error so let's see the second argument to model must be a pojo or string interesting so the second argument of the model i think we misspelled that this should have been a lowercase not an uppercase right so anyway once we have that let me just go ahead and refresh this real quick right so there we go and uh now we would have a bunch of useful methods linked to our user model right so you can see that i can create i can delete i can find all that good stuff based on our schema itself right so yeah that's pretty much it for this video in the next one let's just go ahead and see how we can create a user and how we can probably log in the user as well in the next one so that's all for this one i'm gonna see you in the next one really soon hey everyone welcome back and in this video let's just go ahead and take a look at how you should actually register a user using the correct way right so first things first what i'm going to do is i'm actually just going to show you what we get in the request.body so if i go ahead and hit save and if you go ahead and take a look here if i submit this you can see if i go back to the console nope not this one this one you can see that we have a username and password and actually we have a uh you know warning again in the mongoose connection so let me just go ahead and fix it real quick i think this is this is what the option was right use create and extru yeah so the warning is gone and we are good so anyway you could see that if i submit it here we have username and passwords right now as a developer i mean it's fine when you're developing locally you can see passwords and everything but when you store it in a database all sorts of people have access to database and i'm i mean internally right if you're running a company or a startup you might have people who are working as analysts right so they are just analyzing data there might be some scripts reading databases right uh if you're creating i don't know some sort of way to interact for others to interact with your database why would you do that but you know just an idea then you might have an open api access to your database so well this is this is a little bit of a stretch but anyway the the point i wanted to convey is that your database is not the place where you should store passwords in plain text right you want to encrypt the password somehow but you also want to make sure that other people are able to authenticate themselves easily so what we do is we follow a practice known as hashing the passwords right what is hashing the passwords well think about uh you know cooking food right so you have all the ingredients for example salt pepper sugar oil whatever it is at the beginning right so consider those ingredients as your password or maybe like the ratio in which you use those ingredients as your password now you go ahead and as a cook as a chef so just to create an analogy here real quick cook is gonna be you as a developer ingredients like salt uh pepper um let's see what else did i talk about oil and vegetables i don't know it could be anything these are like password parts of passwords right whatever so as a cook what you do is you you know just create food out of this thing right so this thing is converted into a food like thing food basically not really food like thing but can you tell me once you have the final food with you can you tell me the exact ratios of whatever ingredients now there might be a lot of ingredients here so can you really tell me the exact ratio of what ingredients did you use probably not now i'm not saying that it is impossible but it is improbable right similarly with passwords what we do is we pass it through a special function which is a mathematical function which converts this plain text password into garbage right now this garbage right here is just like your food now you know it is possible it is very very unlikely but that you are able to reverse this thing to get an actual password so yeah i mean hashing passwords is important in terms of security because even if your database is leaked somehow like you know even if you are somebody who's working all alone you might think that why would i need a hashing function then even if your database is leaked somehow then also you know people are not able to reverse all the passwords right they would have they would definitely have a lot of miscomfort and discomfort sort of thing when they are trying to extract real password out of hashes so yeah i mean you should as a developer always always hash the passwords when you are managing them yourself right so the algorithm which will be using for you know the library the package which you will be using is known as bcrypt right and there are a bunch of hashing algorithms that are one-way hashing like you know cooking the food there are md5 there are sha1 sha 256 shj512 there's a long list right but with passwords what we want is we want that not only that they are hashing a particular password into another one a couple of more things are required like you know first of all the collision now i don't i don't really want to get into a depth of this but just to give you an idea the collision should be uh improbable right so collision means that two same sort of strings generating a same hash right so i can say one is also generating this and 100 is also generating this then that is not really you know worth it right and the second thing is that the algorithm should be slow right now this might be this might sound a little bit weird but this is true in case of passwords at least that your hashing algorithm should not be super fast that means it should not be like completed in a couple of clock cycles of the cpu and why is that because this prepares us against the fact that if your database is leaked online then somebody's just not able to brute force at a very high computation uh speed right because you know if your algorithm is fundamentally slow mathematically then it would be slow to brute force as well and you know just adding a couple of clock cycles on uh on a valid attempt would not really hurt you a lot but this would hurt exponentially much to an attacker right who's just trying to brute force a password from a garbage form to an actual password right so these are the two reasons so anyway i think much with the theory let's just go ahead and implement this thing so for this purpose for this uh this this sort of video i'm just going to make use of something known as bbcrip js right which is a js implementation bcrip js which is a js implementation of the bcrypt library right now bcrypt is a low-level library if you install yarn at bcrypt what you're gonna get is a node package around uh i think c or c plus plus binary right or maybe i don't know see yeah i think it's c or c plus plus so that binary i think is 30 40 percent faster but it is non-portable right so you have to download it install it and compile it on any system you want so i'm just going through going with the bcrip js in this one but if you want you can go with bcrypt as well and the binaries both have same syntax right so because i had installed b crypt js i'm gonna do bcrypt is equal to required bcrypt js right and that's it if you do install bcrypt you can just on with.js and you'll be good to go now the next thing i want to do is i want to say that hey first of all let me just go ahead and see i want to hash the password now hash sync is basically a synchronous version which i would say avoid so i want to hash the password first of all let's just get the passwords right so i'm going to get username and password like this request.body right now i want to say that username your password should be hashed so let's just see what bcrypt echoes out now the hash function of bcrypt you can see that it accepts the first argument as the string and the second argument as the salt or number right so salt or number basically just means this number means the how many iterations of bcrypt do you want to run right so you can either go ahead and specify a random string as a salt if you want or you can go ahead and specify a number like 10 or 15 right don't really go crazy with this because that will make your program extremely slow otherwise so 1015 is a good choice you can go ahead and put 10 or 15 or 20 or whatever you want and this means the just as like i said this just means number of times beaker would run on this password so let's just go ahead and see what this echoes so i'm going to go ahead and submit this and you can see that we get the username password like this and the password after bcrypt is something like this right so it's sort of weird but uh um yeah that's that's the point of encryption right the point of hashing that you don't really want it to be guessable so if i go ahead and you know just put a crazy password and submit it you can see that the password is very long but our hash is still of fixed length so this is kind of a you know an advantage for us as developers that we have a fixed length of password to store always in the database right so irrespective of how long the password user makes you can always get a fixed length of password so yeah i mean if we go ahead and use this as plain text password what i can go ahead and say is i can say password is actually bcrypt dot hash sync password and with 10 rounds of salt right so this is not really hash sync just hash so this is basically the username password combination now we have is going to be something which you want to throw in your database right so yeah that's that's pretty much it for this video i'm gonna see you in the next one real soon in which we'll be actually putting this record in the database so yeah see you in the next one real soon hey everyone welcome back and in this video let's just go ahead and take a look at uh you know storing this record in the database now so we just took a look at all the theory and the exciting stuff in the last video let's just go ahead and now actually put this record in the database right so what i'm going to do first of all is i'm going to throw this in a try catch block and i'm just going to tell you the reason in a while just stick with me here i'm just going to console.log error here and i'm just going to return restauration status error for now i'm going to explain this why i'm doing this right so what i want to try is i want to try to create a record so i'm going to say user dot create remember user is the model of mongoose which we imported which is this file right here right i'm going to say user.create and then i'm going to pass in username and password right so remember the password is you know which the one which we created like this and the plain text this should obviously be plain text password right and this would actually go ahead and create a record for us so i'm gonna just say result like this and i'm gonna say console.log or maybe like not really respond rest like this because we already have a address right here right so if i go ahead and console.log this response let's just go ahead and see what happens so i can say user created successfully something like this and uh once we take a look here if i refresh this if i say admin and admin right here and summit you can see that in the preview we get status ok which is absolutely fine right that means we did not get this catch block here and if we go ahead and take a look in the terminal we can say user created successfully with the response value being the actual record which we just created right so we have the id sort of thing for the person which we could probably use for you know jwt authentication for example right which we'll take a look at later on so yeah i mean that's that's basically how you're going to create a new record for the user now the reason i wanted to you know just put this and try catch log is because let's just go ahead and try to summit the form again and this time you're going to see that we get status error instead of status okay so you know what went wrong well if we take a look in the console you can see that we get a error right which says duplicate key error collection right now why did this happen is because if we go ahead and take a look in the schema you're gonna find that we had a unique true assigned to the username right so that means no two users can create a record with the same user name which is pretty cool because we get this validation just out of the box and for the most part this is required in almost every application right you never really want two users having same username or email addresses so yeah that's that's how you're gonna do it that's pretty much it for this video in the next one we're gonna be seeing how we can handle the errors gracefully and just let the client know about things as well so that is all for this one i'm gonna see you in the next video hey everyone welcome back and in this video let's just go ahead and see how we can error how we can handle these errors right so you see usually with node you're going to see errors like this but what is really happening is errors sometimes have a bunch of different properties but most likely a lot of errors have a message property like this right so if we go ahead and take a look at this message property and sum it the same form you're gonna see we get this message like this and if i uh you know try to just go ahead and probably json.stringify this error object we're gonna have a better representation of what all we can pick up right so if i go ahead and submit this you can see the stringified implementation of the error object is something like this right so what we can do is we can probably go ahead and pick up this dot code right so the error.code if it is 11 000 that is you know probably binded to the duplicate error key message so that is exactly what we're going to do we're going to say if error.code is equal to you know not really code but 11 000 right here which means that this is a duplicate key duplicate key so i'm gonna just go ahead and say status error and error is duplicate or maybe like username already and use right something like this otherwise i probably just want to throw the error itself right because this means that something else has gone terribly wrong it might be like um you know your connection might be broken and it might not have been restored for a long time the mongoose your connection in which case it is probably better to crash your program and let it restart or there's something else right there's some permission issue something else right so you don't really want to handle the error which you don't really know about so that's that's basically it and once you have a status okay that's also fine one more thing which you could do is pretty much just go ahead and say right here a bunch of things you can say that if user name uh like you know if there is no username that is username is empty or you know the username is just not present or type of username is not equal to string you just want to say you know something like return rest.json status error this is something which i follow personally the status data error sort of object where you perform the status you give the status as ok or error the error is going to contain an error if there is no error then there would have been a different property called data which will just contain a success message or whatever right so once we have this in place the error for this one would be invalid username similarly you can have a similar check for passwords so you can say type of password is not string then you can say invalid password right you can with passwords you can perform another check you can say if password.length is less than i don't know five or 6 or 10 whatever you can just go ahead and say that hey your password should be password too small should be at least six characters right now you can go ahead and implement a regular expression or some sort of thing here as well as a good practice to have all sorts of combination but i'm just going to leave it for now uh for that part right because sometimes it becomes a little bit more of a you know that experience for user where people just don't like your service anymore which is you know just you're just asking about having different variations gaps small so it might get tiring real quick so that's why i just try to keep it at length only right so that's that's yeah that's pretty much it if i try to submit the form now you can see that uh well we get an error inside the promise itself cannot access password before initialization so yep that is because our password is in fact plain text password right because our main password is right here so if i go ahead and submit it again you can see that we have another problem with password so i think we're using it again somewhere here all right so finally if we go ahead and submit this form again you're gonna see that we get nothing on the console but we get username already in use right so if i go ahead and say admin we get an okay status if i go ahead and limit the password you're gonna see we get password too small should be at least six characters so we basically have everything in place what we can just do is we can say that if result.status is equal to okay that means everything went fine otherwise oops otherwise something went wrong right so i can just alert result.error rate so now if i go ahead and refresh this admin and admin and if i submit this you can see we get an error username already in use if i do an admin 2 we'll get same error because well that is also in use admin 3 gets us there right so we could probably just throw in a alert success right there but i don't know it gets the job done right so yeah that completes our successful registration of the user the next step is to login the user right and for that we'll be using jwt so yeah that's that's pretty much it for this video in the next one we're going to be seeing how you can use jwt in order to log in a particular user and yeah just transport the information securely so that's all for this one i'm gonna see you in the next one really soon hey everyone welcome back and in this video we're going to be taking a look at how you can implement jwt login with node.js express and all that stuff now i don't know why people um are so confused usually about jwt it is a very very simple technology and it's very clever actually and i'm just gonna tell you really soon really quick how it works right so we all know that json is uh is a sort of a format which you can follow to send data to and fro right so you can see that in fact even with the apis we are sending json uh like this right with the status key and error key now this is all fun but what happens when you want uh you know your client to say something about their authentication right so what do i mean by that let's let's take a look at why we need json right so every time your client connects to uh not really json or jwt so every time your client connects to server your client somehow somehow has to authenticate who it is right because why because your server is a central you know sort of computer or a group of computers which you control right but client is a computer which you do not control right you do not know what that computer is what is what ip might it have um you know what what sort of person is using it which country it is so you do not know all that stuff unless that computer is connected to you right so your client has to somehow prove that it is saying what it is right so if the client says that it is john then you have the client has to prove to your server that it is in fact john right so there are basically two ways to do that the first one is client proves itself somehow on the request right and the second way is client server share a secret right now what do i mean by this and this is basically a single thing itself if you if you take if you think about it in a in a little bit of depth but the idea here is that this is the jwt region and this is the cookie region right so the cookie is a shared secret between a client and a server so it's basically um you know a sort of a password you can think of which your server sends to the client and every time client connects back to you it sends that cookie back automatically and you as a server restores the session from database or radius or whatever you're using and then you work with the client right so this is this is like uh one way the other way is that this secret you can say the secret itself has certain attributes and certain data stored in itself which automatically verifies why because this secret or maybe like data is non-changeable and we're gonna take a look at that just in this video why this is non-changeable but before that or maybe like we can just go ahead and do that so let's just go ahead and take a look at this jwt dot io website and if i go down here you can see that this is an example of a jwt token right now this looks random at a first glance but this sort of you know interface breaks it down very nicely you can see a jwt token would have exactly two dots um in the in the whole token right which are which acts as a separator for different things right so the first thing that is from starting to the first dot is the header of the jwt payload right and this all of these three parts are actually base 64 encoding of stuff so if you try to decode this from base 64 to regular ascii you're going to get all this stuff right so jwt is not encryption jwt is not for storing sensitive data it's just saying that hey client you can go ahead and use this token to communicate with me and i would automatically know whether you are what you are what you are saying you are or not so you see the main data which we share is this particular payload right so if i go ahead and you know just go to the console and if i say b2a and i paste this payload not really b2a a to b and if i paste this payload you can see i get the json representation of the data which this jwd token is following right so this jwt token is only and only following this much data the rest of the data is just used for a validation right of validation that this data has not been tampered with now how that validation is performed is this light blue text you see right here is the signature is the hash right so you see that with passwords as well we store the hashes of the password we don't store the actual password itself similarly this hash right here is some sort of hash of this data which the server generated right now very cool thing with hashes is that once you change even a small bit in the actual you know payload that is hash of password is x right if you change password even a little bit you know doesn't really matter if you change this o with 0 this would be something else entirely right so this is the good thing about hashes so you know that if this hash has changed if the server determines that hey the hash of the payload which the user sent does not match with the hash which is available in the payload then something is fishy right and you're just gonna reject that request now what is the possible use case of this you know hash validation is that for example if you had something like a field like admin is false on a person right and if somebody just goes ahead and says that admin is true right so if that happens then this hash would not change from that particular person's you know end why because that particular person does not know a secret key which only your server knows right because only you on the server generate the full json token the client just uses it or you know just passes it back to the server so once the client does not know about the hash they cannot really really change the hash that means they would fail the jwt token validation and there is no possible attack right so yeah the main purpose of jwt is to actually store data inside the secret itself a cookie might be something like this and then you have to take on the server you have to take this cookie and extract out the session from a database like redis or but with jwt your data is well inside the payload itself the cookie or the secret itself right so yeah that's that's basically a very small overview of jwt why you're gonna need that and why um sort of it is a good choice it's a good choice because you you know just remove databases from between as a dependency and uh yeah i mean it's it's just keeps your servers a little bit stateless right you don't really have to maintain and store state so that means shareability is much more scalable compared to other solutions one downside of wt obviously is if you can see that the payload would increase um as you increase the number of fields so the best way to not not make sure of that does not happen is that you use minimum amount of fields which you want right just for example username email should be just fine right so there's that so yeah that's that's pretty much it for jwt tokens in the next video we're going to be seeing how we can implement them validate them do all sorts of stuff right so that's all for this one i'm gonna see you in the next one hey everyone welcome back and in this video let's just go ahead and take a look at how you can set up jwt um inside node.js right so first things first let me just go ahead and create an endpoint for api slash login and this is probably not the first thing first the first thing first should be the actual view but anyway it does not matter so i'm just going to say rest.json status okay status nothing much right and let's go ahead and clone this page to create a login.html here right and i'm just going to keep most of the things same probably change it to login login this could change to login as well i don't know right and this one would change to login as well so we get the username password we send it to api login and this time we send it like this if rest.status is okay that means we got the token right so i'm just going to say console.log got the token and the token is going to be result dot data right now this is something which we have to populate so i'm just going to say go back to the server and say data is something random right so now if i go ahead and take a look here if i go ahead and refresh this and go to slash login.html instead we're going to have a login page and if i try to login you can see we get the token as uh well whatever passed right here uh if i say something like coming soon then we'll probably get coming soon right so that's fine now with that thing being working what we really want is first of all we want to evaluate if the username and password sent by the user is correct or not right before actually going ahead and authorizing them with the json token so to do that i'm just going to perform a very simple uh find command on the database right so i'm going to say user is user dot find one because we're sure that there's only one user right and i'm just going to pass in username and password like this now there's just one problem with this and i can just go ahead and pass in on lean because we don't really need all that mongoose magic so the dot lean just returns us a very json simple object representation of the document right instead of all that fancy mongoose methods so the only problem here is that the password which you see the user is going to write the plain text password again right but if you remember we did not store the plain text password in the database because that was unsafe we stored the decrypt version of the password so there's no way that this query would ever succeed for any user because well bcrypt has almost a different format than plain text password the problem here will be that the password which you compare is gonna be plain text just like i said and it's not going to match the database now the you know the feature of bcrypt not really a problem but a feature of bcrypt is that a single uh conversion will never return in the same string what do i mean by that let's just go ahead and require b crypt inside this b crypt js and do a hash sink of hello with a two iteration right you see we get this string if i try to run the same command again you're going to see that we get a different output you know this is cisa 7 this is q7vq right so if i run this a lot of times you can see that the output is never same right so you cannot really pre-compute the hash and then compare it like that that won't work so what you have to do in order to actually make this work is firstly you have to find the record anyway right you have to find the record anyway without the password but now you have to be very very careful that you use the inbuilt library function right so you want to say that if bcrypt dot compare the password which is you know the password which you're passing as a plain text and the actual hash of the user which is gonna be user dot uh password in this case right and we can just await it this means that the username password combination is successful and how do we know that the username is correct because we were able to find a record number one the password is correct because the hash this dot compare can compare two different uh you know a single string basically and can compare if the hash of that string is one of the possibilities right so there's that now again before this you want to check if the record in fact exists so if it does not exist you want to just say return rest.json status error and error could be invalid username password right you also don't really want to convey the correct information that what is invalid either username or password right because that would just mean that the other person is able to brute force uh for a particular given correct variable so if that is the case well good luck you are clear right so the data would be the token which will come to in a little bit of time if that is not the case what i want to do is i just want to say status error and again basically the same thing invalid username password right and error would be invalid username password now the json the jwt could be and this would be a token which we will generate by using a package known as jwt are not really jwg json web token so let's just go ahead and install it yana json web token there's that now you can just go ahead and import it like jwt is required json web token like this and now you just have to say jwt dot sign and then you have to specify what you want to sign right this could be a string object buffer could be anything now in our case it would be a object and this would be an id of the user so that would be user.id and the username of the user user.username now remember that this information is public that is it is not hidden from user or anybody who's using the browser whatever not really anybody who's using the browser but you know you get the idea on the website so you don't really want to have a very sensitive information like credit card or something here right because it is visible publicly so you just want to have minimum bare minimum information and there's that but this sign right here you can see the sign actually expects you to pass in a secret or a private key as well so for secret we're just going to be using a long string so you can say jwt secret something like this and define it somewhere safe in your environment variable and you can just bang your head on the keyboard for this one and it will just work fine right you can probably just go ahead and insert some more special characters or whatever but yeah you get the idea so once we have our jw jwt secret we're gonna be sending the token like this now remember the secret is super duper important because if this is leaked then all of your json payloads could be manipulated right because they could be signed again by the end user so you absolutely want to make sure that nobody in the world knows what your jwt secret is right this is the only responsibility you have to take care of at the end because if somebody knows and you have to change the secret then all the previous jwt tokens would become invalid right so that's there's that that's you have to take care about now once we have that in place let's just go ahead and take a look so firstly i'm going to go back or maybe like open in a new tab so i'm going to go to the registration page i'm going to say mahul and mahul and submit the form and i get success now if i go back to login and if i try to log in submit the form you can see we still get the success token and we get got the token as this one right now if i go ahead and try to a to b this that is decode this part but we don't want to decode the whole token we just want to decode the middle part which is the actual data you can see this is what the server centers right the id was mongoose id the username is mehul and this iat time is basically when the token was created so yeah now i have this json token with me jwt token on the front end i can send this token every time back on the database on the server and the server would immediately know if i am a whole or not right because if i try to tamper this data right here with username this hash right here would change which is the end hash and i have no way to pre-compute this right i have no way to compute a new hash for the changed data so that's why this data is secure so yeah that's pretty much it for the jwt uh token generation in the next one let's just create an api which is actually something which only private users should access and we'll see how that goes like right so that's all for this one i'm gonna see you in the next one really soon hey everyone welcome back and in this video let's just go ahead and see how we can create an endpoint an api endpoint in node.js to actually let the user change the password right now by this what i mean is that obviously the logged in user can go ahead and change their existing password but we'll be using only jwt tokens for authorizing the user so first things first let me just go ahead and create a new endpoint saying api slash change password right and the request response of this is going to be something like this so i'm going to receive a token first of all which is b which is going to be present in request.body right you could probably receive this as a header as well if you want but i'm not really a fan of that if you if you are then you can receive it in a header as well if you want but request.body is also fine right now once you have that this token right here is json web token so your very very first thing before doing anything at all is to make sure that this token is not tampered with right so how you do that again we're going to be using the same jwt token and we're going to be using this verify method right so this verify method is gonna take in a bunch of things so the first thing is the token obviously which is what we received and the second argument is gonna be our secret key which we use to sign it so that it can verify and decode the thing now once you do that it's going to give you the decoded version of the middle part that is this particular thing right it will just omit the signature you know the signature and the actual payload uh verification for you so that you can only get the body out of it so i can just say user like this and if you go to the verify you can see that if we try to probably console.log it here we're gonna see what happens right so if i go ahead and do that let's just go ahead and actually rest.json this uh status okay as well right so if we go back to index.html copy this create a new file called changepassword.html right just copy paste this and right here just take a look at password and summit right what we're gonna do is we're gonna get the new password value i'm gonna say new password is password right and i'm going to also include the token here now how do we get the token we're going to be getting the token from local storage so i'm going to say localstorage.get item token but for this one what we need to do is we need to also set the token once we receive it so instead of you know got the token uh we can also say local storage dot set item token and the token would be result dot data right so it stores the token inside local storage so that it can persist on refreshes as well now some people sort of frown up on local storage for using json web tokens because it can be leaked with an xss attack or something like this but personally i'm not very uh sure about you know if this is a bad practice right because if you have your site under your control if you're not letting anywhere the user user data to go unsanitized right there is not really a lot of scope for xss these days if you are implementing the content security policy in the correct way uh if you are sanitizing sanitizing the user input uh if you're doing all sort of stuff if you know what you're doing right if you're using um the correct tools for the correct jobs but nonetheless this is still a security concern for a lot of people and i'm not saying that this is absolutely fine and they are just lying and that is not a concern it is a concern if your code base is too huge to mod to be monitored or for you know if you know that there are definitely excesses vulnerabilities then you should not store it in the local storage but otherwise it's probably okay right because if somebody is able to access uh you got bigger problems as well right so anyway once we have the token with us we are sending it like this i want to send it to change password instead of register right and uh yeah rest of the stuff remains the same so let's just go ahead and log in again with me mahul and if i submit this let me just refresh this first of all login summit got the token okay and now if i go ahead and see the local storage you can see we have the token now if i go to change password and it says registration but it should probably say change password hit save refresh and now if i go ahead say one two three four five hit summit you can see we get success well nothing happened on the back end but you know it's fine we see that we call change password right but if you go back into the console you can see that we get this log right here which is the log from this statement so i can say this is jwt decoded like this and if i go ahead and submit this again we get success and i get jwd decoded like this now let's just try to become fishy and try to mess around a little bit so what i'm going to do is i'm going to copy this request as a fetch request and i'm going to go back to console and i'm gonna paste this right here right so this is an actual request which is being performed when i click on this button but what i'm gonna do here is i'm gonna take this payload you know the center the middle of the data and i'm gonna run this through a to b you see we get this data i'm gonna json.parse it right oops let's see json.bars so we get this object right here now i'm going to say x dot username is admin right so i will try to change the admins username and i'm going to say you can see x is this json.stringify x and then i can say b2a to this whole thing right so we got a new payload and if i try to go ahead and take a look at the request again which we had earlier so let me just go ahead and copy this copy as fetch go back go to console paste it right here and paste the malformed uh payload right so i'm gonna replace the center payload with the payload which is gonna consist of admin right as the username and you can see that there's not much change in the uh the payload itself but the only change is going on here in a few characters right but this change is sufficient enough for the signature match to fail so if we go ahead and hit this as enter what is going to happen is we get an internal server error and the reason for that is because this json verification fails you can see it fails by saying invalid signature that means that signature was not valid for the payload which we received so that means nobody can just really you know mess around with your stuff just like that so there's that right so you probably want to throw this in a try catch because you don't really want your server to crash every time somebody performs a malformed action i can say status error error you know somebody is trying to mess around with you right and [Music] yeah that's that's basically how you're going to get the user you can say console.log user now and now once you are at this point you are pretty sure that the payload has not been messed around with and the user is what you think the user is right so now you can say that the id of the user is from user.id because remember that we were storing the id of the user like this and now you can go ahead and pretty much say something like inside an async block obviously user oops user.update1 and you can say the id like this and you can say set password to be the hashed password right so you're going to have to hash the password again so hash password is going to be await becryp dot hash not sync just hash the new password is coming from the body again so i'm going to have a new password right here new psswrd right there right and there's how you update it right you can probably throw in your password verification things right here so these were our verification things right so you probably might want to extract that out in a separate function itself but uh you get the idea so i'm gonna destruct it like that and uh there we go right we can probably replace this with password itself psswrd and then we can get rid of this so there's that right so now you can finally say status okay and you can get rid of this all together so oops something's wrong password like this right so yeah that's that's pretty much it that's how you're going to update a user let's see how if it works or not so let me just go ahead and refresh this my initial password was me hold i'm now keeping it mehul 1 summit did right so if i go back oops oh i get that uh winky eye right because i think my payload is corrupted so let's just go ahead and log in it again mayhew mayhew summit we got the success message go back change password i'm going to change this to mehul 1 summit and we still get that well let us see why is that so if we go ahead and take a look at the console log of the error we'll be able to see that if i summit this we get illegal arguments string and undefined and that is because of the wrong argument count of course right we were using 10 rounds of salt before so we'll be using that only so let's just go ahead and just submit it now and we see success now right so there's that now if i change it to mayhew 5 submitted we get success again so now if i go back to login and if i log into html if i try to sign in with mahul and mayhew it's not gonna work right because the password is changed but if i try with me five it works fine right so yeah that's that's basically how to implement a login registration and for you know password reset like that so that's all for this video i'm gonna see you in the next one really soon all right guys welcome back to the final video in which i just want to give you a little bit of direction where you should go next right so we have covered the fundamentals of everything required for a basic authentication right you have api endpoints you can register users you can login them with json jwt and you can update sort of some settings as well which is just the password in this case now what i would want you to do as a homework practice as an extension to what we have covered so far is to go ahead and implement a sort of a profile dot html page as well here so try to implement and profile.html page which shows a bunch of more information for the user now this could be name address age gender anything you like and you can you know just have blank fields there now once the user saves that you're going to pretty much follow the same format but you can have a different api endpoint here you can say app.post api update profile and you can just go ahead and based on jwt authentication just like we did with the chain password you can go ahead and update their profile right names and everything and all that stuff now if you want to make it more interesting you can add github links and all that stuff but yeah once you get the hang of it how it is all happening then it is not very difficult to do anything like that so yeah that's that's basically what is happening when you are trying to register uh on a page which uses jwt and username passwords so it's as simple as that right i hope you are clear with what's really happening all along right there's nothing very rocket science going on here very much so yeah again if you have any doubts you can go ahead and ask it below in the discussions but that's all for this video and this little mini course as well hope you enjoyed it and if you did the next steps after you just woke up with the extension is to obviously just go ahead and follow along with the node.js back in developer learning path we have completed this one project uh more projects would be added here soon but you can always go ahead and take a look at this and you can start working on different different things as well so that is all for this one i'm gonna see you in the next one really soon
Info
Channel: codedamn
Views: 67,473
Rating: 4.9446368 out of 5
Keywords: nodejs, nodejs login, nodejs mongodb, nodejs register, register node, login nodejs, login with node, login nodejs tutorial, nodejs authentication, register login node, nodejs signup, username password nodejs
Id: b91XgdyX-SM
Channel Id: undefined
Length: 68min 3sec (4083 seconds)
Published: Fri Oct 23 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.