VOOZH about

URL: https://dev.to/jane49cloud/where-to-impliment-password-encryption-in-nodejs-4e7k

⇱ Where to impliment Password Encryption in node.js - DEV Community


Security is one of the most essential features of any application.
We mainly impliment this through hashing password. Today I will focus on implimenting this in a MERN app.
The basic structure of a neat node application has the following basic folders and files

connection(database)
models (defines properties of models.)
conrollers (handlers of Crud operations)
routes(defines paths || Url mapping)

Encryption in controllers

Assuming you are already connected to the database and have created a users model, install bcrypt
npm i bcryptjs

# backend/controllers/users.js
const User = require('../models/user') //path to your user model
const bcrypt = require("bcryptjs")

const registerUser = async(req,res)=>{
const {name, email, password} = req.body

//first check if the user exists
 const userExists = await User.findOne({ email });
 if (userExists) {
 response.status(400);
 console.log("Email address already exists")
 }

 //Encrpt password before you save
 const salt = await bcrypt.genSalt(10);
 const hashedPassword = await bcrypt.hash(password, salt);
}

//create user 

try {
const user = await User.create({
 name,
 password: hashedPassword,
 email
 });
 res.json(user);
 console.log(user, "User created successfully...")

} catch (error) {
 console.log(error, `User not created...`)
};

module.exports = {
 registerUser,
};

import the registerUser controller and route your user register path and test your application. I used postman to register a user and got the following json response:

{"name":"Luke Graham","email":"graham@gmail.com","password":"$2a$10$rQrhLmwoEGaCMq9qR9cLaOvVBtA/FvoSSmt1tGj0gq7tFyscDS5jK","photo":"https://i.ibb.co/4pDNDk1/avatar.png","phone":"+245","bio":"bio should be at most 250 characters","_id":"6371eb2668c624ddb1bd72d9","createdAt":"2022-11-14T07:15:50.078Z","updatedAt":"2022-11-14T07:15:50.078Z","__v":0}

The password was hashed successfully.
Do not give a maxLength to the password in the model because the hashed password gives a long string. Validate in the frontend.
The above method is valid. However, there are moreother controllers that require password.

*registerUser
loginUser
updatePassword
forgotPassword
*

for each of the above handlers you need to configure encryption.
Therefore it is easier to perfom the encription in the model file.
Use a schema.pre() function that changes the password before saving.
This is how it is implimented:

#backend/models/users.js
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");

const userSchema = new mongoose.Schema({
 name: { type: String, required: true },
 email: {
 type: String,
 required: true,
 unique: true,
 trim: true,
 match: [
 /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
 "Please enter a valid email address",
 ],
 },
 password: {
 type: String,
 required: true,
 minLength: [6, "password must be at least 6 characters"],
 },
 photo: { type: String, required: true ,
 default: "https://i.ibb.co/4pDNDk1/avatar.png"}, // person avatar
 phone:{type:String, default: "+245"},
 bio:{
 type:String, 
 maxLength:[250, "bio must be at most 250 characters"],
 default: "bio should be at most 250 characters"
 }
},
{
 timestamps:true
}

);

//Encrypt password before saving to database

userSchema.pre("save", async function(next){
 if(!this.isModified("password")){
 return next()
 }
 const salt = await bcrypt.genSalt(10);
 const hashedPassword = await bcrypt.hash(this.password, salt);//this.passord (points to the password in this file)
 this.password = hashedPassword
next()
})


module.exports = mongoose.model("User", userSchema);

Just a few adjustments in the model and password is pashed before the schema is saved.
There are a few changes in the controller file

#backend/controller/user
const User = require('../models/user') //path to your user model

const registerUser = async(req,res)=>{
const {name, email, password} = req.body

//first check if the user exists
 const userExists = await User.findOne({ email });
 if (userExists) {
 response.status(400);
 console.log("Email address already exists")
 }
 //create user 
try {
const user = await User.create({
 name,
 password,
 email
 });
 res.json(user);
 console.log(user, "User created successfully...")

} catch (error) {
 console.log(error, `User not created...`)
};
module.exports = {
 registerUser,
};

route your application and test. My response:

{"name":"Mercy","email":"mercy@gmail.com","password":"$2a$10$iqzkaO1wTco.3z1KK8Ij9u9sy2DtLViRwL5lvgeHDcQ31wPfCo9jK","photo":"https://i.ibb.co/4pDNDk1/avatar.png","phone":"+245","bio":"bio should be at most 250 characters","_id":"6371fe23225d25b4e3e8220c","createdAt":"2022-11-14T08:36:51.311Z","updatedAt":"2022-11-14T08:36:51.311Z","__v":0}

The password was successfully hashed. Hoping this helps understund encryption better and how to use it better.

Was this article helpful?
Need clarification?
Leave a comment