There are lots of tutorials about user authentication but all of them are just covering the topics like how to sign up and how to sign in. Even if you find a tutorial about reset password then you will see that it covers old school method without APIs and using jQuery based front-end. In this tutorial, we are going to use a Node.js based API which will connect to Angular front-end. Let’s get started: Initializing the project init npm So I assume you are already familiar with generating projects with Node.js and Angular or React. So will not go further for basic topics. We need to install the Express framework, Body-parser, and Mongoose and other required dependencies (We are using Mongo DB) and Node mailer for sending the link to your email where you can set a new password. npm express nodemailer mongoose cors cookie-parser install body-parser bcrypt Let’s create our main server file: express = ( ); mongoose = ( ); cors = ( ); cookieParser = ( ); auth = ( ); app = express(); app.use(cors()); server = ( ).createServer(app); dbConfig = ( ); app.use(express.json({ : })); app.use(express.urlencoded({ : , : })); app.use(cookieParser()); mongoose.Promise = global.Promise; mongoose.connect( dbConfig.url, { : } ).then( { .log( ) }).catch( { .log(err) }) app.use( , auth); server.listen( , () => { .log( ); }); const require 'express' const require 'mongoose' const require 'cors' const require 'cookie-parser' const require './routes/authRoutes' const const require 'http' const require './config/secret' limit '50mb' extended true limit '50mb' useNewUrlParser true ( ) => conn console "Mongo Connected" ( ) => err console '/api/resetpassword' 3000 console 'Listening on port 3000' You may notice that we added a Mongo DB URL from the config folder. You can use Mongo DB Atlas and insert URL by yourself. You might also notice authroute which is not created yet. We will do it later. However, before it we are going to create User model Creating Users Model bcrypt = ( ); mongoose = ( ); Schema = mongoose.Schema; userSchema = Schema({ : { : , : [ , ], : [ , ] }, : { : , : [ , ], : [ , ], : , : , : , : [ ] }, : { : , : [ , ], : [ , ], : }, }); userSchema.statics.EncryptPassword = { hash = bcrypt.hash(password, ); hash;}; .exports = mongoose.model( , userSchema); const require 'bcryptjs' const require 'mongoose' const const new username type String min 5 'Too short, min is 5 characters' max 32 'Too long, max is 32 characters' email type String min 5 'Too short, min is 5 characters' max 32 'Too long, max is 32 characters' unique true lowercase true required 'Email is required' match /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/ password type String min 5 'Too short, min is 5 characters' max 32 'Too long, max is 32 characters' required 'Password is required' async ( ) function password const await 12 return module 'User' We are using bcrypt for hashing our user's password. Also, we need a create a model for reset token. Here is how it will look like. mongoose = ( ); resettokenSchema = mongoose.Schema({ : { : mongoose.Schema.Types.ObjectId, : , : }, : { : , : }, : { : , : , : .now, : }, }); .exports = mongoose.model( , resettokenSchema); const require 'mongoose' const new _userId type required true ref 'User' resettoken type String required true createdAt type Date required true default Date expires 43200 module 'passwordResetToken' Creating Auth Controller It’s time to create an auth controller that will contain all controller functions. bcrypt = ( ); crypto = ( ); nodemailer = ( ); User = ( ); passwordResetToken = ( ); .exports = { CreateUser(req, res) { userEmail = User.findOne({ : req.body.email }); (userEmail) { res .status( ) .json({ : }); } userName = User.findOne({ : req.body.username }); (userName) { res .status( ) .json({ : }); } bcrypt.hash(req.body.password, , (err, hash) => { (err) { res .status( ) .json({ : }); } body = { : req.body.username, : req.body.email, : hash }; User.create(body) .then( { res res.status( ) .json({ : , user }); }) .catch( { res .status( ) .json({ : }); }); }); }, const require 'bcryptjs' const require 'crypto' const require 'nodemailer' const require '../models/users' const require '../models/resettoken' module async const await email if return 409 message 'Email already exist' const await username if return 409 message 'Username already exist' return 10 if return 400 message 'Error hashing password' const username email password => user 201 message 'User created successfully' => () 500 message 'Error occured' For making reset password work we first need to create an account. In the above, you will see the controller function which can be used for registering a user. We use for hashing a password. it's also recommended to use or e for adding extra validation. You might think why both and were required. Later we will use for Bcrypt Joi xpress-validator bcrypt crypto crypto resettoken There is a debate which one of those libraries are better and which one can be selected in different situations. The main point of using both of them in this tutorial was that you can see in which cases each of them can be used and how? Creating ResetPassword controller function ResetPassword(req, res) { (!req.body.email) { res .status( ) .json({ : }); } user = User.findOne({ :req.body.email }); (!user) { res .status( ) .json({ : }); } resettoken = passwordResetToken({ : user._id, : crypto.randomBytes( ).toString( ) }); resettoken.save( { (err) { res.status( ).send({ : err.message }); } passwordResetToken.find({ : user._id, : { : resettoken.resettoken } }).remove().exec(); res.status( ).json({ : }); transporter = nodemailer.createTransport({ : , : , : { : , : } }); mailOptions = { : user.email, : , : , : + + + resettoken.resettoken + + } transporter.sendMail(mailOptions, (err, info) => { }) }) }, async if return 500 message 'Email is required' const await email if return 409 message 'Email does not exist' var new _userId resettoken 16 'hex' ( ) function err if return 500 msg _userId resettoken $ne 200 message 'Reset Password successfully.' var service 'Gmail' port 465 auth user 'user' pass 'password' var to from 'your email' subject 'Node.js Password Reset' text 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' 'Please click on the following link, or paste this into your browser to complete the process:\n\n' 'http://localhost:4200/response-reset-password/' '\n\n' 'If you did not request this, please ignore this email and your password will remain unchanged.\n' Above controller function generates a token which consists of random bytes and attaches it into the URL which will be included in the email. We use Node mailer to send email to the user and as a service provider Gmail was selected for this tutorial, but you can use Sendgrid's API. You can include from which email to send this email, customize the text and include your project’s domain name as the main URL. Localhost:4200 was added because Angular is running locally on that port. However this functionality works a bit slow and not enough well on the localhost. Wile it will behave perfectly in production mode when you will deploy it and connect with your domain name. ResetPassword Validating Token and setting a new password Here is the final controller function which will be used for submitting new password. ValidPasswordToken(req, res) { (!req.body.resettoken) { res .status( ) .json({ : }); } user = passwordResetToken.findOne({ : req.body.resettoken }); (!user) { res .status( ) .json({ : }); } User.findOneAndUpdate({ : user._userId }).then( { res.status( ).json({ : }); }).catch( { res.status( ).send({ : err.message }); }); }, NewPassword(req, res) { passwordResetToken.findOne({ : req.body.resettoken }, { (!userToken) { res .status( ) .json({ : }); } User.findOne({ : userToken._userId }, { (!userEmail) { res .status( ) .json({ : }); } bcrypt.hash(req.body.newPassword, , (err, hash) => { (err) { res .status( ) .json({ : }); } userEmail.password = hash; userEmail.save( { (err) { res .status( ) .json({ : }); } { userToken.remove(); res .status( ) .json({ : }); } }); }); }); }) } } async if return 500 message 'Token is required' const await resettoken if return 409 message 'Invalid URL' _id => () 200 message 'Token verified successfully.' ( ) => err return 500 msg async resettoken ( ) function err, userToken, next if return 409 message 'Token has expired' _id ( ) function err, userEmail, next if return 409 message 'User does not exist' return 10 if return 400 message 'Error hashing password' ( ) function err if return 400 message 'Password can not reset.' else return 201 message 'Password reset successfully' Before submiting the new password it verifies the token with user ID. Creating API routs Before completing the back-end we need to create authrouter file that will include all endpoints. express = ( ); router = express.Router(); AuthCtrl = ( ); router.post( , AuthCtrl.CreateUser); router.post( , AuthCtrl.ResetPassword); router.post( , AuthCtrl.NewPassword); router.post( , AuthCtrl.ValidPasswordToken); .exports = router; const require 'express' const const require '../controllers/auth' '/register' '/req-reset-password' '/new-password' '/valid-password-token' module That’s it! The back-end is ready and completely functional. We need to care about the front end now. To check the second part of this tutorial please visit by this link