This is the third part of this authentication series with nodejs and mongoDB. If you have not checked out the previous parts, please check out part 1 and part 2.
In this part of the tutorial, we will be covering the login with jasonwebtoken (JWT)
. By the end, we will have seen how to crosscheck users and match the hashed password
to the plain text password
.
Without wasting anytime, let's jump into it.
Starter Project
If you are not coming from the previous tutorial, then you can get the starter project from here
Login Endpoint
- Install JWT
npm i jsonwebtoken -s
- Import
JWT
just below theconst bcrypt = require("bcrypt");
line at the top of theapp.js
file like so:
const jwt = require("jsonwebtoken");
- Just below the
register
endpoint, enter the following function:
app.post("/login", (request, response) => { })
- Let's check if the email the user enter on login exists with the following line of code:
User.findOne({ email: request.body.email })
Next, we will use a then...catch...
block to check if the email search above was successful or not
- If it is unsuccessful, we will capture that in the
catch
block like so:
User.findOne({ email: request.body.email }) .then() .catch((e) => { response.status(404).send({ message: "Email not found", e, }); });
- If successful, we will compare the password entered against the hashed password in our database. We are doing this in the
then...
block like so:
.then((user)=>{ bcrypt.compare(request.body.password, user.password) })
We will then use a then...catch...
block again to check if the comparison is successful or not
- If the comparison is unsuccessful, we will return an error message in the
catch
block like so:
.then((user)=>{ bcrypt.compare(request.body.password, user.password) .then() .catch((error) => { response.status(400).send({ message: "Passwords does not match", error, }); }) })
- Let's double check if the password is correct in the
then
block
.then((passwordCheck) => { // check if password matches if(!passwordCheck) { return response.status(400).send({ message: "Passwords does not match", error, }); } })
- If the password matches, then create a random token with the
jwt.sign()
function. It takes 3 parameters i.e.jwt.sign(payload, secretOrPrivateKey, [options, callback])
. You can read more here
bcrypt.compare(request.body.password, user.password) .then((passwordCheck) => { // check if password matches if(!passwordCheck) { return response.status(400).send({ message: "Passwords does not match", error, }); } // create JWT token const token = jwt.sign( { userId: user._id, userEmail: user.email, }, "RANDOM-TOKEN", { expiresIn: "24h" } ); })
- Finally, return a success message with the token created
.then((user)=>{ bcrypt.compare(request.body.password, user.password) .then((passwordCheck) => { // check if password matches if(!passwordCheck) { return response.status(400).send({ message: "Passwords does not match", error, }); } // create JWT token const token = jwt.sign( { userId: user._id, userEmail: user.email, }, "RANDOM-TOKEN", { expiresIn: "24h" } ); // return success response response.status(200).send({ message: "Login Successful", email: user.email, token, }); })
- Our Login Endpoint now looks like this:
// login endpoint app.post("/login", (request, response) => { // check if email exists User.findOne({ email: request.body.email }) // if email exists .then((user) => { // compare the password entered and the hashed password found bcrypt .compare(request.body.password, user.password) // if the passwords match .then((passwordCheck) => { // check if password matches if(!passwordCheck) { return response.status(400).send({ message: "Passwords does not match", error, }); } // create JWT token const token = jwt.sign( { userId: user._id, userEmail: user.email, }, "RANDOM-TOKEN", { expiresIn: "24h" } ); // return success response response.status(200).send({ message: "Login Successful", email: user.email, token, }); }) // catch error if password do not match .catch((error) => { response.status(400).send({ message: "Passwords does not match", error, }); }); }) // catch error if email does not exist .catch((e) => { response.status(404).send({ message: "Email not found", e, }); }); });
Testing
- Let's try to login with the credentials we registered in the last tutorial. See the random
token
generated on a successful login
- If
email
is incorrect or does not exist
- If
password
is incorrect
At this point, you can put hands together for yourself because you have just conquered AUTHENTICATION
👏🏼👏🏼👏🏼👏🏼👏🏼
Conclusion
We began this authentication series by setting up out database in PART 1, we created a model for the user
collection and a register
endpoint in the PART 2 and finally, in this part, we have successfully created the login
endpoint checking if users exist or not.
Congratulations!!! 🍾🍾🍾
We will look into Protecting Endpoints from unauthenticated users next. I hope to catch you there.
Meanwhile, all codes are here
Top comments (4)
eiii please am not getting you ooo
I hope the call made things clearer.
It is important to pay attention to every detail. That is why I make the tutorial step by step. I also make indicators on the screenshots.
Please Follow these indicators
Where was the user data added to the database?
Please make things more clearer
I hope the call made things clearer.
It is important to pay attention to every detail. That is why I make the tutorial step by step. I also make indicators on the screenshots.
Please Follow these indicators