MERN Authentication Tutorial #3 - Signing Up & Hashing Passwords

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay so we have some routes and controller functions set up to handle sign up and login requests and we also have a user model so that inside those controller functions we can use it to do things like save new users to the database when they sign up and that's ultimately what we want to do we want to take the email and password of a user that they tried to sign up with and save those into a user's collection in the database so we're storing our users but also when we do this we don't want to save their password in its original form to the database that's going to be a security risk because if the database was ever breached then everyone's password would be exposed so instead what we need to do is Hash their password before we save it to the database that way if the database did get breached then it would just be a load of unreadable hashed passwords that get exposed and the same would be true for users logging in we wouldn't compare plain unhashed passwords to verify their identity we'd compare hash passwords instead to make sure they match and then log them in if they do match so in this lesson we'll be focusing on the sign up controller to sign new users up and save them to the database but also on how we're going to Hash their passwords before we do save them to the database as well now when it comes to writing all of this logic we could do it directly inside the signup controller that's definitely an option but I want to show you another way that we can do this as well and that's by creating what's known as a static method on our user model so when we create models with Mongoose they automatically come with methods like create or find or find one and delete that we can use to do things for us with the database but we can also make our own and that's what we're going to do so we're going to make a static method on our user model called sign up so then we can just call that method whenever we want to sign up a new user and save them to the database so inside the user model file let's do a little comment first of all that says something like static sign up method all right and then to make a static method we just take our user schema that we already created and we use a property called Statics on it and then we say dots and then whatever method that we want to create in our case we want to create a sign up method so we can say DOT sign up and then we set this equal to a function in our case it's going to be an async function because we're going to use asynchronous code inside it to handle all of the sign up logic and then later we can just call the sign up method on the user model whenever we want to sign up a new user so this right here is how we create an additional static method on a model all right so let's flesh this out a little bit first of all I want to take in two arguments to this function whenever we call it the first one is the email and the second one is the password they want to sign up with all right so inside here we want to check if first of all this email already exists in the database because if it does then we don't want to even try and sign them up and now we have this over here saying it must be unique and that's like an extra layer of security for us but if we can just do a quick check ourselves to say look if this email already exists then we'll just send back some custom error response so let's do that I'm going to say const and I'll call this exists set it equal to a weight and then normally we would say user dot find one but right here we don't have the user we export that model right here and we import the user model elsewhere but we don't really have the user at the minute now when we create a static method like this instead of using the model name we can just say this and that refers to the model essentially so we want to find one and we want to find it by the email so we pass that in as the criteria and that's the email they're trying to sign up with so if this exists then this is going to have a value if it doesn't it's going to be null so what we can do down here is a little check to see if it exists so if this has a value then we want to send back some kind of error now we're not going to use the response right here because we don't have access to it instead what we're going to do is throw an error right here so we say Throw error and then later when we use this sign up function we'll catch the error if there is one and then it will send the response so for now we're just throwing errors inside this function so we'll throw it here and the message is going to be email already in use okay so that's the first thing we need to do if this is null it means that email doesn't exist we can use it so it bypasses this and at this point we want to save that user to the database that email and password but remember first of all we want to Hash this password and to do that we'll be using a package called be Crypt so let me first open up the terminal and then I'm going to cancel out of this node process control C and then I'm going to install it by typing npm install decrypt like so and press enter so bcrypt is a hashing function that can hash our passwords in a secure way and that means that if our database was compromised the passwords values inside the database would still be protected that's not to say that hackers wouldn't be able to figure out the passwords from hashes through Brute Force attacks or something like that but it would still provide a high level of protection and give you time to let your users know about the data breach so that they can change their own passwords if they need to decrypt also forces us to use something called salt when we're hashing the passwords as well now assault is basically a random string of characters that gets added to the user's password before it gets hashed and it just adds an extra layer of security to it because it means that if two people use the same password if the salt for each of those passwords was different then the resulting hash would be different as well so it prevents Hackers from password matching if they manage to crack one since the hashes for identical passwords will be different thanks to that salt so the way we typically do this is by first of all generating assault and then hashing that together with the password then we store the resulting hash in the database all right so to generate the salt we can just say const salt so that's what we're calling our constant but you can call it what you want and we say that that's equal to a weight B Crypt and then use a method called gen salt and we invoke that method now we use a weight because this step takes time to complete by Design and we also pass in an argument to this function which is the number of rounds or the cost of the sole the higher the number the longer it will take for potential hackers to crack passwords but also it takes longer for users to sign up as well so you need to find a balance the default value is 10 and for the sake of this tutorial we're going to stick with 10 as well so this generates our salt and now we need to Hash that with the password so to do that we can say const hash is then equal to a weight be Crypt and then we use a method called hash and we invoke that method and now we need to pass in two arguments the first one is the plain text password that the user wants to use to sign up and log in with and the second one is the salt value which we just generated so we pass in those two and then that's pretty much it so now bcrypt is hashing the password that the user created to sign up with and we have that in this hash constant now now we need to take this password down and store it in the database alongside the user's email to create what is essentially a record for that user in a database or in no SQL terms a document for that user so down here we're going to say const user is equal to a weight and then we use this to use a method to refer to the model much like we did up here and the method is create to create a new document we're going to pass in an object which represents that document and the two properties we want are the email which we get past in right here and the second one is the password so password but the value of this is going to be the hash so we can say that's equal to the hash okay and then that is going to create this document for us and down here we need to return that so we return the user right here because remember we're going to call this function from elsewhere and when we do that it's going to return that user for us so that's all we need to do inside this function next we can go over to the user controller and inside the sign up use a function we can use that so remember we already grabbed the user right here this user model and now we can use a method called sign up on it first what I'm going to do is grab the email and password from the request body so I'll say const email and password is going to be oops that needs to be in curly braces because we're destructuring from an object we set that equal to request dot body and then after that we want to try and sign the user up now we need to wrap this up in a try catch block because we need to catch an error if there is one this error right here so let's go over here and we'll say try and then after that catch any error if there is one like so now the thing we want to try is to sign up basically so we'll say const user is equal to a weight and then the user model DOT sign up the new function we just created and remember we pass in two arguments the email and password so let's pass those things in email and password all right and that's pretty much all we need to do for that little bit the next thing we need to do is send a response so if this is successful and it doesn't throw an error then we know we get a user back because we returned it down here so I can say down here we want to set the status to something like 200 and then we'll send back some Json and the Json we send back is going to be the email of the user that they're trying to sign up with and also the user object so the new documents created in mongodb all right so that's all we're doing inside this try block down here when we catch the area if there is one or say response dot status and we're going to set that to be 400 and then after that we're going to send back some Json and there's going to be an error message right here so error and the error is going to be the message of this error object so we'll say error.message now in this case over here it would be this message if we throw this error but also it could be a different error from Mongoose when we try to do something like create one of these users so if something doesn't match up this will throw an error as well we'll catch it and we'll send that back all right so we no longer need this thing down here and this is now all done so now when we send a request to forward slash sign up it's going to fire this code it's going to use this sign up function on the user model which we have right here it's going to see if that user exists if it does it throws an error we send that back if it doesn't we create a soul and hash the password then we try to create that new user and we return the user so over here we grab that user right here and then we send back a response with a status of 200 and some Json with the user's email and also that new document that they tried to sign up with so we're going to test this out in a second but just quickly I want to go back to the user model and I think I used yes I use Arrow functions right here now we can't do that when we're creating this because we're using the this keyword inside of it so we need to use a regular asynchronous function so I'm going to say right here the function keyword and then we can take away the arrow so this needs to be a regular function not an arrow function otherwise something like this won't work where we're using this keyword all right so now what I'd like to do is save this make sure you have this running over here and I want to try this out in Postman this this particular function right here so the end point if we go to the routes which is forward slash sign up so let's give that a whirl all right then so now in Postman let's just try this route right here to sign up so as you can see it's a post request and this is the email I want to sign up with Yoshi at netninja.dev this is the password and by the way we are going to implement some server side logic later on to validate these values to make sure this is an email and this is a strong password for example but for now any values will do so let's send this request and see what we get back and hopefully we should see the email yeah we do and also the new user document that was created awesome so we can see the email this is the hashed password now that we can see and also the unique user ID that mongodb applies so awesome all of this is now working
Info
Channel: Net Ninja
Views: 38,305
Rating: undefined out of 5
Keywords: MERN, MERN stack, MERN tutorial, MERN auth, MERN authentication, MERN auth tutorial, MERN authentication tutorial, MERN stack tutorial, auth, auth tutorial, authentication tutorial, jwt, jwt tutorial, json web tokens, json web tokens tutorial, node auth, node auth tutorial, jwt auth, jwt auth tutorial, express auth, password hashing, bcrypt, hashing, password hash
Id: mjZIv4ey0ps
Channel Id: undefined
Length: 13min 19sec (799 seconds)
Published: Wed Jul 20 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.