22. Encrypting Passwords
password which is stored in database must not be in plain text for security purpose it must be stored in hashed or encrypted format
signup API is used to register users to database
app.post("/signup", async (req, res) => { const user = new User(req.body); try { await user.save(); res.send("data saved success"); } catch (err) { res.status(404).send("error:- " + err.message); } });
whenever user register first time these steps must be followed before saving the data to DB
i) validation of data
ii) encrypt the password
iii) then create a new instance of the User model
In validation of data step we mostly write logic to validate the data which is in form of helper function
for this we create a folder known as “utils“ in utils create a file known as “validation.js“. We mostly validate the request body.
As validation of field such as email ,password is quite difficult so we use npm package know as “express-validator“ to provide validation of email and password, these packages have inbuilt methods to validate the fields like to tell whether to know whether the password is strong or not we will use a method known as “validator.isStrongPassword(password)“ means there are some fixed criteria which are needed to called a password strong which is stored in isStrongPassword() method
Always carry out the three steps in try…catch block
for encrypting password we use a package known as bcrypt, this package gave us function to hash password and validate it
the function which we use to hash password is “bcrypt.hash()“ it takes parameter as password inputted by the user and salt with number of time that salt is applied, as number of times(basic number is 10) the number of salt as a result that hash password will be strong.
lets understand how password is hashed in general we take password for example “test@123“ and take salt which is string consisting of different characters for example “hsdfsj78eq3@%^vjksjd“ and specify number of times salt will round around password to make encryption level deeper but keep is mind in general we do 10 round as the number of round is increased it will take more time for encryption and then we get password which is encrypted one which is never decrypted until and we know the password.
there is also a function know as “bcrypt.genSalt()“ which is used to generate salt
const { password } = req.body; //encryption of data const passwordHash = await bcrypt.hash(password, 10); console.log(passwordHash);//$2b$10$/uPiBVLZG4ClknZFQuKgXu3DINpJsaCpuejDWvpPrcWYbhFxwlVIq
while creating a instance of model it is recommended to explicitly specify the field which we want. const user = new User({ firstName, lastName, emailId, password: passwordHash, });
if we specify any other fields other than mentioned field explicitly will be ignored while sending data from client.
app.post("/signup", async (req, res) => { try { //validation of data validateSignUpData(req); //whetever request comes it is validated here const { firstName, lastName, emailId, password } = req.body; //encryption of data const passwordHash = await bcrypt.hash(password, 10); console.log(passwordHash); //creating new instance of User model const user = new User({ firstName, lastName, emailId, password: passwordHash, }); await user.save(); res.send("data saved success"); } catch (err) { res.status(404).send("error:- " + err.message); } });
above we can see the password which is hashed.
Now lets create a login API where we check whether the entered emailId and password matched our database emailId and password.
here we will use bcrypt.compare() function, in this we pass two parameter one is plain password and other parameter is hashed stored in database one which is compared and give result as true or false.
app.post("/login", async (req, res) => { try { const { emailId, password } = req.body; //check whether the emailId which we are getting is matching the database or not then manipulate the respected password const user = await User.findOne({ emailId: emailId }); if (!user) { throw new Error("email Id not present"); } const isPasswordValid = await bcrypt.compare(password, user.password); if (isPasswordValid) { res.send("login successful"); } else { throw new Error("Invalid credentials"); } } catch (err) { res.status(404).send("error:- " + err.message); } });