Create and store new users in the database
This lecture builds the create-user flow for a MERN app, from a Mongoose schema through password hashing with bcrypt to catching duplicate email errors.
A working backend needs more than a route that says a user was created; it needs to actually store that user safely in the database, with a password nobody can read in plain text. This lecture picks up right where the previous one left off, connecting a frontend request all the way through to a saved, hashed record in MongoDB.
Building the Mongoose user schema
The first step is creating a schema that Mongoose can use to talk to MongoDB. Inside a new models folder, a user.js file imports mongoose and defines a schema with three fields: name, email, and password. Each field gets a type of String. The name field also uses trim, which strips extra spaces a user might accidentally add, and required: true, since a user can't exist without a name. The email field adds unique: true, because while two users could share a name, they can't share an email address, which is what uniquely identifies each account. The finished schema is exported with module.exports so it can be imported into the controller.
Creating and saving a new user
In the controller, the schema is imported and used to build a new user object from the payload sent by the frontend: const { name, email, password } = req.body. That data is passed into a new instance of the schema with the new keyword, and the response is sent back as JSON. Testing this with Postman shows the new user object coming back correctly, including an _id field that MongoDB automatically adds. But at this point the data isn't actually saved yet. Calling .save() on the new user object is what writes it to the database, and because that's an asynchronous operation, the function needs to be marked async and the save call needs await in front of it.
Hashing the password with bcrypt
Storing a password as plain text is a serious security problem: anyone who gets access to the database can read every user's password directly. The fix is the bcrypt dependency, installed with npm install bcrypt. Inside the schema file, a pre('save') middleware function runs before every save operation. Inside it, this.isModified('password') checks whether the password field was actually changed. If it was, bcrypt.hash() is used to hash it, with a salt value added to make the hash harder to crack. A salt somewhere around 8 to 10 is recommended; going much higher, like 100 or 150, slows down account creation without adding meaningful security. The hashed result replaces this.password before the save proceeds, and since bcrypt's hashing is asynchronous, the pre-save function itself needs to be async with an awaited hash call.
Validating duplicate emails and status codes
Even with the schema's unique: true constraint, sending a duplicate email produces a raw database error rather than a clean response. To handle this properly, the controller checks for an existing user with the same email before creating a new one, using User.findOne() with the given email, awaited inside an async function. If a matching user is found, the response returns an error message saying the email is already in use, along with a 401 status code, since a duplicate email is treated as an authorization-style error. When account creation succeeds, the response explicitly sets a 200 status rather than relying on the default.
Key takeaways
- A Mongoose schema defines field types plus constraints like
required,unique, andtrim. - Creating a new document with
new User(...)doesn't save it; you need an awaited.save()call. - Passwords should never be stored as plain text; hash them with bcrypt inside a
pre('save')middleware hook. - A bcrypt salt value around 8 to 10 balances security against performance.
- Checking for an existing user with
findOne()before saving lets you return a clean, specific error instead of a raw database exception. - Explicit status codes, like 401 for a duplicate email and 200 for success, make API responses easier to handle on the frontend.
Who this is for
This lecture is built for developers following along with a MERN stack course who are implementing user creation for the first time, and it's a practical reference for anyone adding secure password storage to a Node and MongoDB backend.
Full transcript(auto-generated, with timestamps)
[0:03]Hi everyone till our last lecture we saw how to establish a connection from our front end to our backend AP system and from our backend AP system to our database that is the mongodb database but now uh in this lecture we are going to actually send a payload from our uh front end or back end API and the back end apis will actually read it and take out the data and store it in our database so uh this will complete the process and actually send uh send out a response like it was user was created successfully so in this lecture we are going to create a new user for our
[0:41]Application where a system where you can create new new users in our application I'm excited for this course come on let's get started to actually communicate from our uh backend API to our uh mongod database the we need to use a dependency called mango which is what we used to uh to connect in our last lecture so you can see that our dependency in know dependencies uh we have already uh installed so uh then next step in the process is to create a user schema using which will help us store it in mongodb database so to create a user schema inside of file I'm going to create a new
[1:29]Folder called models inside that folder I'm going to create a new file called user.js and this use inside this user.js first step is to uh import the inside our uh inside this file so equal to require mango that's so we have imported mango into our system uh file the next step is to uh create our user schema using mongus to do that F user schema equal to mango. schema Mangus has an inil function for creating schema that will help us uh have lots of inbuilt commands for it uh so that we can you can use it just to if we give
[2:40]Like do save or do delete it will actually do it in our database directly this is similar to hyber netm that we if you will be familiar to if you had used spring boot if you're not familiar with that it's not a problem we can actually get to know about this in this course so we are going to have three fields for our user name and then to give it a type our name type is going to be string and next is uh we are going to have column called trim what does this trim do is uh trim excludes the extra space after the name is included like if
[3:39]Someone has included their name like Manish and then Manish after Manish they have added by mistake two Extra Spaces then this trim will actually trim the extra space that is that is the use of this uh trim function and then uh required is equal to true because we cannot have a user without a name that is a required field so required and I'll will just copy paste this two more times for uh email and password and in inside email field we need to have an extra uh uh extra field called uh unique because we we use email to uniquely identify a specific user because two or three users can have same
[4:41]Name but we in our system uh they can't have a same email ID if a person has a uh two or three email if in then with the person name we have two or three ladies we can consider them as separate uh users so unique true this is password password everything is uh similar to like in the name and then I'm going to and we have created an user schema now we just need to export this user schema so that it can imported in other files so do do that module do exports equal to do
[5:53]Model user uh you can give it any name I'm giving it as user and this user schema should be used from this just copy paste it so that you don't make any spelling mistake yes and this is it from uh from our modules file now we just need to use this user schema to import it into our controllers so to import our uh models uh in in in this controller file we just need to give the same procedure const require const user equal to require dot dot slash models Slash use we don't need to give JS over here because uh uh it will identify by itself
[7:07]It will only identify the JavaScript files inside the models and then uh instead of actually sending just create new user I'm going to send another response of uh the new users information first to get the new users information we get it from our front end right uh front end will uh actually call the API and actually send the new new users information in the payload so to read that payload we read it from require. body so I'm now reading the payload con you can do that name comma email comma password equal to require. body and this will uh uh uh take the inputs that is sent from the uh payload
[7:59]Into the name email and body and then now we are going to create a new user schema with the the with the name that is name email and password that is sent from the uh payload front end payload uh to do that uh uh H new user uh equal to new we use this new keyword and user this user is the cons that we imported here so that will import the schema and just pass the name email and password inside it now new user is created the next step is we'll actually send in the response we'll just send this new user and check it how how the new user uh are we
[9:04]Receiving the information correctly and we are sending it back okay so I we always need can communicate only in Json format from front end to back end so I have change it to response. Json and user new user that's it now let us just check it from our Postman how this is working perfectly and I'm going to call that API with the inside the body Jason we are sending name is test email is test at gmail.com and password is 1 2 3 some sort of come oh sorry I haven't started the application till now so that is the just
[10:18]Stop starting this application might take little bit time because uh to establish a connection with the mongodb database Le takes quite some time yeah the DB is connected and server is running successfully on P 8080 now if we give this uh AP send this AP request it should be working fine sending and we got the result one thing to note in the uh result that response that we got you we have underscore ID one field extra added with uh after name email and password that we sent this is the ID that uh mango uh dependency has added to this schema so
[11:30]That it can specifically identify a new user in that schema but uh has this been now saved in our database let's check it check our database see user and just refresh it no nothing has been saved in this database till now why hasn't been it has not saved the data in the database is because we we have to add this command to actually save it new user dot save and it will just save it to our database see how simple it makes the Mong dependence has made it to communicate with the mongodb database has use new user. save and uh one more thing to add is this uh
[12:20]New user. save this anything any communication with our database is actually an asynchronous function so we might need to add this a wait keyword in front of it otherwise a keyword can only be used inside of asynchronous functions uh that is so we need to make this an asynchronous function or I think we can uh skip this weight part over here new user. save that's it just let's just run our application and check if it is done our application would have restarted
[13:32]Right now and just now now I'm sending it see the ID is getting every time the ID is getting different value because in our new schema we schema is adding different ID underscore ID during every API call so if should check it now in our database and just if we refresh it see we has been saved in our backend database successfully but one thing to not is that see the password is abruptly directly saved in our database which is not a good thing because if anyone who gets hold of the database will get get to know what is the use what are all the user and all the user users password
[14:20]Which is not a very secure way to store in our the database So to avoid that what we should do is every time and the password is changed or it is actually saved we need to actually hash the password before saving it so to Hash the password we actually use a dependency called bcrypt that I have actually already installed in my uh project bcrypt to install it in your project you just need to uh give npm install bcrypt and it will uh include it into your project uh so after after installing break next step is to inside our models click inside our models we need to ha it every time some
[15:08]The password was updated so do that to do that uh first we need to import uh uh bcrypt just like we imported so copy this is bcrypt BT so bcrypt has been imported now we are going to use this bcrypt hash or password uh to do that first we are going to add this command users schema dot pre off save what this actually means is save is the function that we are using it to save it to our database right this pre means before saving before saving the it in database uh it will always uh uh implement this function and which which is like
[16:19]Function we don't want request and response over here this shouldn't be present over here and inside this this function we need to check if the password was actually uh modified so to use that we are using if this dot is modified of password which means it will check if our password was modified during the before this save and last save so it will actually inside the the if if the password was modified then we need to hah the password and save it into database to hah the uh password uh we use bcrypt bcrypt dot hash this. pass
[17:30]Good comma we need to add a in hashing we always need to add a salt to it so how much of the greater the value of the salt it is that much tougher for someone to crack the hashed password and also don't keep for that don't keep very high value like 100 or 150 as the Sol because then while saving and uh the saving your creating a user itself will take time for your uh uh application us so which will slow slow your application so don't do that I will recommend to use value around 8 to 10 that is itself hard for other people to crack so I'll give
[18:12]Around eight as dis solved and then we have to this hash password should be saved in our the password right this dot password equal to bcrypt of uh hash b.h this. password and we need to add one more command over here is to add the aite or here because this is an this makes it into an asynchronous function so and we have to mention it over here and we need to have a next function inside this because uh uh what is this next function I will explain it uh in this lecture after later on but this next is actually used because this function is a middle bar function we
[19:18]Need to actually understand it uh what while teaching you about what a middle bar function is I'll just explain you what this next fun function actually does this we need to call next here no I think should save this case some showing as yoube no I think some
[20:31]Why this uh okay they showing you you need a uh this password equal to I think it should be fine let me check what is the error in the ter app crash start password invalid left hand sment some issue is happening over in here
[21:43]What is the so here wait this do password equal to bp. hash yeah actually the I think I found out the error just that we need to add this a command only for the bcrypt because bcrypt is the one that is actually uh using the asynchronous function the this. password and a bcrypt and that that should be saved into this. password that's it now the issue would be resorted yeah we can check our
[22:57]Terminal and yeah I think it will Su yeah server is running on P successfully and I I expected the DB is connected successfully now uh if we actually uh give uh give the uh call the same API but one thing to notice unique if we give this test gmail.com then it will give it will give out an error in our system just to show you that I actually send email same as tested gmail.com it is going to give out some error because we have in our database we need we have made it as a you can see see it's mentioned do duplicate key key error collection then
[23:53]Movie reviews. users so it won't be saved in our database so to avoid that what we need to do is we have to change the test uh change it to test uh test 1@gmail.com and then send the same uh and some I think elections okay the duplicate key error hasn't been solved so okay yes just restart the project because of which the app had crashed before now if we restart the project it will actually again start running the project then we can actually call the API now just click on send yeah it has been successful we didn't get any in the terminal now if we go check in our
[24:59]Mongod database and refresh it see for the test one gmail.com the password is f no one can find out what is the password that we sent from our uh frontend uh application so that is successful but one more uh mistake that can happen over in here is if someone sent an empty email that you you can't store an empty email right so we need to add validations to check if it is the email is uh empty and also we need to send an error message when this person is sending the same email right here the response is showing it to be success but in our database it has been it was not
[25:48]Saved perfectly so to identify that what we need to do is in our uh controller user user.js going to controller user.js there before updating a new user we need to check if that same user already uh if the same email ID already exist in our database so to do that uh const old user equal to await see I am using await again because it is a uh now I'm going to communicate with the database and it's an asynchronous process I want it to be completed before moving on to the no Next Step that is why I'm using a wait You user do find one this will find one email ID that is
[26:49]Already there in the system if if at all if there exist one in our system so I'll give this email as the input and I I need to change the function as an asynchronous function because I have added a we over here right so I I have to change it to an asynchron uh change this into an asynchronous function I have made it into n plus function then now uh I I will check if the old user uh uh if the old user length is greater than zero then there exists an old user uh with the same email ID then then we just return it saying that uh
[28:03]You you this email ID is already in use that's it so do that if hold user then return response dot uh Jason this email ID is already in use that's it you need to add the error message is already news and E that's it and this will send the error message and one thing to actually add is like we need to also send a status while sending the error message otherwise it will always assume it is the success statement and it will send the status is
[29:16]Uh 20 to send uh when the email ID is already in use it is actually considered an uh authorization uh error so to do for which we send uh regularly send the code AS 401 so I'm going to add that to this command status status 41j and similarly for when it is success and we are sending new new user we should send the success as status as 200 till now it was a defa 200 is default so it was using again and again the 200 but it's better to specify what should be the status and if we now go go to the postman and again send
[30:13]This request see we are getting 401 unauthorized error and then the email ID is already in use so that is success
More videos
2:08Bridging the Pixel Gap in Browser Automation.
2:23How One Narrow Safety Rule Can Make an AI Less Safe Everywhere Else.
2:04Why splitting a chunk from its document makes it retrieve for the wrong question
4:20Three You Can Take Back. One You Can't.
2:21Why a 50-turn agent pays for the same screenshot 35 times unless it caches the pixels
1:53